backup: add freeotp+ support

This commit is contained in:
Bilal Elmoussaoui 2020-12-08 03:43:24 +01:00
parent ebb4452abe
commit ffea8efdac
2 changed files with 66 additions and 1 deletions

View file

@ -1,7 +1,8 @@
use super::{Backupable, Restorable};
use crate::models::ProvidersModel;
use crate::models::{Account, Provider, ProvidersModel};
use anyhow::Result;
use gettextrs::gettext;
use gio::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -21,6 +22,33 @@ impl Backupable for FreeOTP {
}
fn backup(model: ProvidersModel, into: gio::File) -> Result<()> {
let mut items = Vec::new();
for i in 0..model.get_n_items() {
let provider = model.get_object(i).unwrap().downcast::<Provider>().unwrap();
let accounts = provider.accounts_model();
for j in 0..accounts.get_n_items() {
let account = accounts
.get_object(j)
.unwrap()
.downcast::<Account>()
.unwrap();
items.push(account.otp_uri());
}
}
let content = items.join("\n");
into.replace_contents(
content.as_bytes(),
None,
false,
gio::FileCreateFlags::REPLACE_DESTINATION,
gio::NONE_CANCELLABLE,
)?;
Ok(())
}
}

View file

@ -273,6 +273,8 @@ impl Account {
let priv_ = AccountPriv::from_instance(&account);
priv_.token.set(token);
println!("{:#?}", account.otp_uri());
account.init();
account
}
@ -378,6 +380,41 @@ impl Account {
priv_.token_id.borrow().clone()
}
pub fn otp_uri(&self) -> String {
let provider = self.provider();
let label = self.name();
let issuer = provider.name();
let hmac_algorithm = provider.hmac_algorithm().to_string();
let secret = self.token();
let digits = provider.digits();
match provider.algorithm() {
Algorithm::HOTP => {
format!(
"otpauth://hotp/{}?secret={}&issuer={}&algorithm={}&digits={}&counter={}",
label,
secret,
issuer,
hmac_algorithm,
digits,
self.counter()
)
}
_ => {
format!(
"otpauth://totp/{}?secret={}&issuer={}&algorithm={}&digits={}&period={}",
label,
secret,
issuer,
hmac_algorithm,
digits,
provider.period()
)
}
}
}
pub fn set_name(&self, name: &str) -> Result<()> {
let db = database::connection();
let conn = db.get()?;