mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 16:54:45 +01:00
few code cleanup
This commit is contained in:
parent
b07804368b
commit
9b5d4a4d0b
5 changed files with 47 additions and 33 deletions
|
@ -1,5 +1,4 @@
|
|||
use super::{Backupable, Restorable};
|
||||
use crate::helpers::Keyring;
|
||||
use crate::models::{Account, Algorithm, HOTPAlgorithm, Provider, ProvidersModel};
|
||||
use anyhow::Result;
|
||||
use gio::{FileExt, ListModelExt};
|
||||
|
@ -123,15 +122,9 @@ impl Restorable for AndOTP {
|
|||
}
|
||||
};
|
||||
|
||||
match Keyring::store(&item.label, &item.secret) {
|
||||
Ok(token_id) => {
|
||||
let account = Account::create(&item.label, &token_id, &provider).unwrap();
|
||||
provider.add_account(&account);
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Failed to restore account {}", e);
|
||||
}
|
||||
};
|
||||
if let Ok(account) = Account::create(&item.label, &item.secret, &provider) {
|
||||
provider.add_account(&account);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -195,10 +195,13 @@ glib_wrapper! {
|
|||
}
|
||||
|
||||
impl Account {
|
||||
pub fn create(name: &str, token_id: &str, provider: &Provider) -> Result<Account> {
|
||||
pub fn create(name: &str, token: &str, provider: &Provider) -> Result<Account> {
|
||||
let db = database::connection();
|
||||
let conn = db.get()?;
|
||||
|
||||
let token_id = Keyring::store(&format!("{} - {}", provider.name(), name), &token)
|
||||
.expect("Failed to save token");
|
||||
|
||||
diesel::insert_into(accounts::table)
|
||||
.values(NewAccount {
|
||||
name: name.to_string(),
|
||||
|
@ -308,17 +311,12 @@ impl Account {
|
|||
Algorithm::Steam => 1,
|
||||
};
|
||||
|
||||
// Modified version of an implementation from otpauth crate
|
||||
let key = hmac::Key::new(provider.hmac_algorithm().into(), self.token().as_bytes());
|
||||
let wtr = counter.to_be_bytes().to_vec();
|
||||
let result = hmac::sign(&key, &wtr);
|
||||
let digest = result.as_ref();
|
||||
let ob = digest[19];
|
||||
let pos = (ob & 15) as usize;
|
||||
let mut rdr = std::io::Cursor::new(digest[pos..pos + 4].to_vec());
|
||||
let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fff_ffff;
|
||||
let otp = base % 10_u32.pow(provider.digits() as u32);
|
||||
|
||||
let otp = generate_otp(
|
||||
&self.token(),
|
||||
counter,
|
||||
provider.hmac_algorithm().into(),
|
||||
provider.digits() as u32,
|
||||
);
|
||||
self.set_property("otp", &otp.to_string()).unwrap();
|
||||
}
|
||||
|
||||
|
@ -343,6 +341,11 @@ impl Account {
|
|||
let clipboard = display.get_clipboard();
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
clipboard.set_text(&priv_.otp.borrow());
|
||||
|
||||
// Indirectly increment the counter once the token was copied
|
||||
if self.provider().algorithm() == Algorithm::HOTP {
|
||||
self.generate_otp();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> i32 {
|
||||
|
@ -354,6 +357,7 @@ impl Account {
|
|||
let provider = self.get_property("provider").unwrap();
|
||||
provider.get::<Provider>().unwrap().unwrap()
|
||||
}
|
||||
|
||||
pub fn counter(&self) -> i32 {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.counter.get()
|
||||
|
@ -396,3 +400,22 @@ impl Account {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_otp(
|
||||
token: &str,
|
||||
counter: u64,
|
||||
algorithm: hmac::Algorithm,
|
||||
digits: u32,
|
||||
) -> u32 {
|
||||
// Modified version of an implementation from otpauth crate
|
||||
let key = hmac::Key::new(algorithm, token.as_bytes());
|
||||
let wtr = counter.to_be_bytes().to_vec();
|
||||
let result = hmac::sign(&key, &wtr);
|
||||
let digest = result.as_ref();
|
||||
let ob = digest[19];
|
||||
let pos = (ob & 15) as usize;
|
||||
let mut rdr = std::io::Cursor::new(digest[pos..pos + 4].to_vec());
|
||||
let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fff_ffff;
|
||||
|
||||
base % 10_u32.pow(digits)
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ static PROPERTIES: [subclass::Property; 11] = [
|
|||
"default_counter",
|
||||
"default_counter",
|
||||
0,
|
||||
1000,
|
||||
i32::MAX,
|
||||
1,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
|
@ -505,7 +505,7 @@ impl Provider {
|
|||
&priv_.filter_model
|
||||
}
|
||||
|
||||
pub fn search_accounts(&self, text: String) {
|
||||
pub fn filter(&self, text: String) {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
let filter = gtk::CustomFilter::new(Some(Box::new(move |obj| {
|
||||
let account = obj.downcast_ref::<Account>().unwrap();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::application::Action;
|
||||
use crate::helpers::{qrcode, Keyring};
|
||||
use crate::helpers::qrcode;
|
||||
use crate::models::{Account, Algorithm, Provider, ProvidersModel};
|
||||
use crate::widgets::{ProviderImage, ProviderImageSize};
|
||||
use anyhow::Result;
|
||||
|
@ -200,13 +200,11 @@ impl AccountAddDialog {
|
|||
let username = self_.username_entry.get().get_text().unwrap();
|
||||
let token = self_.token_entry.get().get_text().unwrap();
|
||||
|
||||
if let Ok(token_id) = Keyring::store(&username, &token) {
|
||||
let account = Account::create(&username, &token_id, provider)?;
|
||||
send!(
|
||||
self_.global_sender.get().unwrap(),
|
||||
Action::AccountCreated(account, provider.clone())
|
||||
);
|
||||
}
|
||||
let account = Account::create(&username, &token, provider)?;
|
||||
send!(
|
||||
self_.global_sender.get().unwrap(),
|
||||
Action::AccountCreated(account, provider.clone())
|
||||
);
|
||||
// TODO: display an error message saying there was an error form keyring
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -89,7 +89,7 @@ impl ProvidersList {
|
|||
|
||||
let accounts_filter = gtk::CustomFilter::new(Some(Box::new(move |object| {
|
||||
let provider = object.downcast_ref::<Provider>().unwrap();
|
||||
provider.search_accounts(text.clone());
|
||||
provider.filter(text.clone());
|
||||
provider.accounts().get_n_items() != 0
|
||||
})));
|
||||
self_.filter_model.set_filter(Some(&accounts_filter));
|
||||
|
|
Loading…
Add table
Reference in a new issue