mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 00:34:40 +01:00
code cleanup
mostly rename hmac_alogrithm -> algorithm algorithm -> method
This commit is contained in:
parent
29bada492f
commit
4223fcf10e
18 changed files with 313 additions and 313 deletions
|
@ -71,6 +71,7 @@
|
|||
<object class="HdyActionRow">
|
||||
<property name="activatable_widget">provider_entry</property>
|
||||
<property name="title" translatable="yes">Provider</property>
|
||||
<property name="subtitle" translatable="yes">The service provider</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="provider_entry">
|
||||
<property name="halign">end</property>
|
||||
|
@ -164,10 +165,10 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="digits_row">
|
||||
<property name="title" translatable="yes">Digits</property>
|
||||
<object class="HdyActionRow" id="algorithm_row">
|
||||
<property name="title" translatable="yes">Algorithm</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="digits_label">
|
||||
<object class="GtkLabel" id="algorithm_label">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
@ -176,10 +177,10 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="hmac_algorithm_row">
|
||||
<property name="title" translatable="yes">HMAC Algorithm</property>
|
||||
<object class="HdyActionRow" id="method_row">
|
||||
<property name="title" translatable="yes">Computing Method</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="hmac_algorithm_label">
|
||||
<object class="GtkLabel" id="method_label">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
@ -200,10 +201,10 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="algorithm_row">
|
||||
<property name="title" translatable="yes">Algorithm</property>
|
||||
<object class="HdyActionRow" id="digits_row">
|
||||
<property name="title" translatable="yes">Digits</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="algorithm_label">
|
||||
<object class="GtkLabel" id="digits_label">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<object class="HdyActionRow">
|
||||
<property name="title" translatable="yes">Dark Theme</property>
|
||||
<property name="activatable_widget">dark_theme_switch</property>
|
||||
<property name="subtitle" translatable="yes">Whether the application should use a dark theme.</property>
|
||||
<property name="subtitle" translatable="yes">Whether the application should use a dark theme</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="dark_theme_switch">
|
||||
<property name="valign">center</property>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<child>
|
||||
<object class="HdyActionRow">
|
||||
<property name="title" translatable="yes">Password</property>
|
||||
<property name="subtitle" translatable="yes">Setup a password to lock the application with.</property>
|
||||
<property name="subtitle" translatable="yes">Setup a password to lock the application with</property>
|
||||
<property name="activatable">True</property>
|
||||
<property name="action-name">preferences.show_password_page</property>
|
||||
<child>
|
||||
|
@ -51,7 +51,7 @@
|
|||
<object class="HdyActionRow">
|
||||
<property name="title" translatable="yes">Auto Lock the application</property>
|
||||
<property name="activatable_widget">auto_lock_switch</property>
|
||||
<property name="subtitle" translatable="yes">Whether to automatically lock the application.</property>
|
||||
<property name="subtitle" translatable="yes">Whether to automatically lock the application</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="auto_lock_switch">
|
||||
<property name="valign">center</property>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<child>
|
||||
<object class="HdyActionRow">
|
||||
<property name="title" translatable="yes">Auto lock timeout</property>
|
||||
<property name="subtitle" translatable="yes">The time in minutes.</property>
|
||||
<property name="subtitle" translatable="yes">The time in minutes</property>
|
||||
<property name="activatable_widget">lock_timeout_spin_btn</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="lock_timeout_spin_btn">
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<object class="HdyActionRow">
|
||||
<property name="activatable_widget">provider_website_entry</property>
|
||||
<property name="title" translatable="yes">Website</property>
|
||||
<property name="subtitle" translatable="yes">Used to fetch the website icon if possible</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="provider_website_entry">
|
||||
<property name="halign">end</property>
|
||||
|
@ -106,6 +107,77 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyComboRow" id="method_comborow">
|
||||
<property name="title" translatable="yes">Computing Method</property>
|
||||
<property name="expression">
|
||||
<lookup type="HdyEnumValueObject" name="name"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyComboRow" id="algorithm_comborow">
|
||||
<property name="title" translatable="yes">Algorithm</property>
|
||||
<property name="expression">
|
||||
<lookup type="HdyEnumValueObject" name="name"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="period_row">
|
||||
<property name="activatable_widget">period_spinbutton</property>
|
||||
<property name="title" translatable="yes">Period</property>
|
||||
<property name="subtitle" translatable="yes">The duration in seconds. The recommended value is 30</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="period_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">period_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="default_counter_row">
|
||||
<property name="activatable_widget">default_counter_spinbutton</property>
|
||||
<property name="title" translatable="yes">Counter</property>
|
||||
<property name="subtitle" translatable="yes">The by default value for counter-based computing method</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="default_counter_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">default_counter_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="digits_row">
|
||||
<property name="activatable_widget">digits_spinbutton</property>
|
||||
<property name="title" translatable="yes">Digits</property>
|
||||
<property name="subtitle" translatable="yes">Length of the generated code, recommended value is 6</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="digits_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="value">6</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">digits_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow">
|
||||
<property name="activatable_widget">provider_help_entry</property>
|
||||
|
@ -121,82 +193,6 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyComboRow" id="algorithm_comborow">
|
||||
<property name="title" translatable="yes">Algorithm</property>
|
||||
<property name="expression">
|
||||
<lookup type="HdyEnumValueObject" name="name"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection_mode">none</property>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="period_row">
|
||||
<property name="activatable_widget">period_spinbutton</property>
|
||||
<property name="title" translatable="yes">Period</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="period_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">period_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyComboRow" id="hmac_algorithm_comborow">
|
||||
<property name="title" translatable="yes">HMAC Algorithm</property>
|
||||
<property name="expression">
|
||||
<lookup type="HdyEnumValueObject" name="name"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="default_counter_row">
|
||||
<property name="activatable_widget">default_counter_spinbutton</property>
|
||||
<property name="title" translatable="yes">Default Counter</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="default_counter_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">default_counter_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="digits_row">
|
||||
<property name="activatable_widget">digits_spinbutton</property>
|
||||
<property name="title" translatable="yes">Digits</property>
|
||||
<property name="subtitle" translatable="yes">Defaults to 6</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="digits_spinbutton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="text">0</property>
|
||||
<property name="adjustment">digits_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -8,6 +8,6 @@ CREATE TABLE "providers" (
|
|||
"digits" INTEGER NULL DEFAULT 6,
|
||||
"period" INTEGER NULL DEFAULT 30,
|
||||
"default_counter" INTEGER NULL DEFAULT 1,
|
||||
"hmac_algorithm" VARCHAR NULL DEFAULT "SHA1",
|
||||
"algorithm" VARCHAR DEFAULT "TOTP"
|
||||
"algorithm" VARCHAR NULL DEFAULT "SHA1",
|
||||
"method" VARCHAR DEFAULT "TOTP"
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{Backupable, Restorable};
|
||||
use crate::models::{Account, Algorithm, HOTPAlgorithm, Provider, ProvidersModel};
|
||||
use crate::models::{Account, Algorithm, OTPMethod, Provider, ProvidersModel};
|
||||
use anyhow::Result;
|
||||
use gettextrs::gettext;
|
||||
use gio::{FileExt, ListModelExt};
|
||||
|
@ -13,8 +13,8 @@ pub struct AndOTP {
|
|||
pub label: String,
|
||||
pub digits: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub type_field: Algorithm,
|
||||
pub algorithm: HOTPAlgorithm,
|
||||
pub method: OTPMethod,
|
||||
pub algorithm: Algorithm,
|
||||
pub thumbnail: String,
|
||||
pub last_used: i64,
|
||||
pub used_frequency: i32,
|
||||
|
@ -55,8 +55,8 @@ impl Backupable for AndOTP {
|
|||
issuer: provider.name(),
|
||||
label: account.name(),
|
||||
digits: provider.digits(),
|
||||
type_field: provider.algorithm(),
|
||||
algorithm: provider.hmac_algorithm(),
|
||||
method: provider.method(),
|
||||
algorithm: provider.algorithm(),
|
||||
thumbnail: "".to_string(),
|
||||
last_used: 0,
|
||||
used_frequency: 0,
|
||||
|
@ -108,7 +108,7 @@ impl Restorable for AndOTP {
|
|||
let provider = model.find_or_create(
|
||||
&item.issuer,
|
||||
item.period.unwrap_or_else(|| 30),
|
||||
item.type_field,
|
||||
item.method,
|
||||
None,
|
||||
item.algorithm,
|
||||
item.digits,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{Backupable, Restorable};
|
||||
use crate::models::{Account, OtpUri, Provider, ProvidersModel};
|
||||
use crate::models::{Account, OTPUri, Provider, ProvidersModel};
|
||||
use anyhow::Result;
|
||||
use gettextrs::gettext;
|
||||
use gio::prelude::*;
|
||||
|
@ -75,13 +75,13 @@ impl Restorable for FreeOTP {
|
|||
.into_iter()
|
||||
.try_for_each(|uri| -> Result<()> {
|
||||
println!("{:#?}", uri);
|
||||
let otp_uri = OtpUri::from_str(uri)?;
|
||||
let otp_uri = OTPUri::from_str(uri)?;
|
||||
let provider = model.find_or_create(
|
||||
&otp_uri.issuer,
|
||||
otp_uri.period.unwrap_or_else(|| 30),
|
||||
otp_uri.algorithm,
|
||||
otp_uri.method,
|
||||
None,
|
||||
otp_uri.hmac_algorithm,
|
||||
otp_uri.algorithm,
|
||||
otp_uri.digits.unwrap_or_else(|| 6),
|
||||
otp_uri.counter.unwrap_or_else(|| 1),
|
||||
)?;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::Restorable;
|
||||
use crate::models::{Account, Algorithm, HOTPAlgorithm, ProvidersModel};
|
||||
use crate::models::{Account, Algorithm, OTPMethod, ProvidersModel};
|
||||
use anyhow::Result;
|
||||
use gettextrs::gettext;
|
||||
use gio::FileExt;
|
||||
|
@ -12,8 +12,8 @@ pub struct LegacyAuthenticator {
|
|||
pub label: String,
|
||||
pub digits: i32,
|
||||
#[serde(rename = "type")]
|
||||
pub type_field: Algorithm,
|
||||
pub algorithm: HOTPAlgorithm,
|
||||
pub method: OTPMethod,
|
||||
pub algorithm: Algorithm,
|
||||
pub thumbnail: String,
|
||||
pub last_used: i64,
|
||||
pub tags: Vec<String>,
|
||||
|
@ -48,7 +48,7 @@ impl Restorable for LegacyAuthenticator {
|
|||
let provider = model.find_or_create(
|
||||
&issuer,
|
||||
item.period,
|
||||
item.type_field,
|
||||
item.method,
|
||||
None,
|
||||
item.algorithm,
|
||||
item.digits,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::models::OtpUri;
|
||||
use crate::models::OTPUri;
|
||||
use anyhow::Result;
|
||||
use ashpd::desktop::screenshot::{Screenshot, ScreenshotOptions, ScreenshotProxy};
|
||||
use ashpd::{zbus, RequestProxy, Response, WindowIdentifier};
|
||||
|
@ -7,7 +7,7 @@ use image::GenericImageView;
|
|||
use std::str::FromStr;
|
||||
use zbar_rust::ZBarImageScanner;
|
||||
|
||||
pub(crate) fn scan(screenshot: &gio::File) -> Result<OtpUri> {
|
||||
pub(crate) fn scan(screenshot: &gio::File) -> Result<OTPUri> {
|
||||
let (data, _) = screenshot.load_contents(gio::NONE_CANCELLABLE)?;
|
||||
|
||||
let img = image::load_from_memory(&data)?;
|
||||
|
@ -23,7 +23,7 @@ pub(crate) fn scan(screenshot: &gio::File) -> Result<OtpUri> {
|
|||
|
||||
if let Some(ref result) = results.get(0) {
|
||||
let uri = String::from_utf8(result.data.clone())?;
|
||||
return Ok(OtpUri::from_str(&uri)?);
|
||||
return Ok(OTPUri::from_str(&uri)?);
|
||||
}
|
||||
anyhow::bail!("Invalid QR code")
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use super::provider::{DiProvider, Provider};
|
||||
use super::{Algorithm, OtpUri};
|
||||
use super::{
|
||||
provider::{DiProvider, Provider},
|
||||
OTPMethod, OTPUri,
|
||||
};
|
||||
use crate::helpers::Keyring;
|
||||
use crate::models::database;
|
||||
use crate::schema::accounts;
|
||||
|
@ -275,8 +277,6 @@ impl Account {
|
|||
let priv_ = AccountPriv::from_instance(&account);
|
||||
priv_.token.set(token);
|
||||
|
||||
account.qr_code();
|
||||
|
||||
account.init();
|
||||
account
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ impl Account {
|
|||
fn init(&self) {
|
||||
self.generate_otp();
|
||||
// Only trigger time-based callback after duration if it's a TOTP
|
||||
if self.provider().algorithm() == Algorithm::TOTP {
|
||||
if self.provider().method() == OTPMethod::TOTP {
|
||||
glib::source::timeout_add_seconds_local(
|
||||
self.provider().period() as u32,
|
||||
clone!(@weak self as account => @default-return glib::Continue(false), move || {
|
||||
|
@ -299,26 +299,26 @@ impl Account {
|
|||
fn generate_otp(&self) {
|
||||
let provider = self.provider();
|
||||
|
||||
let counter = match provider.algorithm() {
|
||||
Algorithm::TOTP => {
|
||||
let counter = match provider.method() {
|
||||
OTPMethod::TOTP => {
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
timestamp / (provider.period() as u64)
|
||||
}
|
||||
Algorithm::HOTP => {
|
||||
OTPMethod::HOTP => {
|
||||
let old_counter = self.counter();
|
||||
self.increment_counter();
|
||||
old_counter as u64
|
||||
}
|
||||
Algorithm::Steam => 1,
|
||||
OTPMethod::Steam => 1,
|
||||
};
|
||||
|
||||
let otp = generate_otp(
|
||||
&self.token(),
|
||||
counter,
|
||||
provider.hmac_algorithm().into(),
|
||||
provider.algorithm().into(),
|
||||
provider.digits() as u32,
|
||||
);
|
||||
self.set_property("otp", &otp.to_string()).unwrap();
|
||||
|
@ -347,7 +347,7 @@ impl Account {
|
|||
clipboard.set_text(&priv_.otp.borrow());
|
||||
|
||||
// Indirectly increment the counter once the token was copied
|
||||
if self.provider().algorithm() == Algorithm::HOTP {
|
||||
if self.provider().method() == OTPMethod::HOTP {
|
||||
self.generate_otp();
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ impl Account {
|
|||
priv_.token_id.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn otp_uri(&self) -> OtpUri {
|
||||
pub fn otp_uri(&self) -> OTPUri {
|
||||
self.into()
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::string::ToString;
|
|||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, GEnum)]
|
||||
#[repr(u32)]
|
||||
#[genum(type_name = "ProviderAlgorithm")]
|
||||
pub enum Algorithm {
|
||||
#[genum(type_name = "ProviderMethod")]
|
||||
pub enum OTPMethod {
|
||||
#[genum(name = "TOTP")]
|
||||
TOTP = 0,
|
||||
#[genum(name = "HOTP")]
|
||||
|
@ -15,12 +15,91 @@ pub enum Algorithm {
|
|||
Steam = 2,
|
||||
}
|
||||
|
||||
impl Default for Algorithm {
|
||||
impl Default for OTPMethod {
|
||||
fn default() -> Self {
|
||||
Self::TOTP
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for OTPMethod {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for OTPMethod {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(OTPMethod::from_str(&String::deserialize(deserializer)?).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for OTPMethod {
|
||||
fn from(u: u32) -> Self {
|
||||
match u {
|
||||
1 => OTPMethod::HOTP,
|
||||
2 => OTPMethod::Steam,
|
||||
_ => OTPMethod::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OTPMethod {
|
||||
pub fn to_locale_string(&self) -> String {
|
||||
match *self {
|
||||
OTPMethod::HOTP => gettext("Counter-based"),
|
||||
OTPMethod::TOTP => gettext("Time-based"),
|
||||
OTPMethod::Steam => gettext("Steam"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OTPMethod {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_ref() {
|
||||
"totp" | "otp" => Ok(Self::TOTP),
|
||||
"hotp" => Ok(Self::HOTP),
|
||||
"steam" => Ok(Self::Steam),
|
||||
_ => anyhow::bail!("Unsupported OTPMethod"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for OTPMethod {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
OTPMethod::TOTP => "totp",
|
||||
OTPMethod::HOTP => "hotp",
|
||||
OTPMethod::Steam => "steam",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, GEnum)]
|
||||
#[repr(u32)]
|
||||
#[genum(type_name = "ProviderAlgorithm")]
|
||||
pub enum Algorithm {
|
||||
#[genum(name = "SHA1")]
|
||||
SHA1 = 0,
|
||||
#[genum(name = "SHA256")]
|
||||
SHA256 = 1,
|
||||
#[genum(name = "SHA512")]
|
||||
SHA512 = 2,
|
||||
}
|
||||
|
||||
impl Default for Algorithm {
|
||||
fn default() -> Self {
|
||||
Self::SHA1
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Algorithm {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
@ -39,22 +118,12 @@ impl<'de> Deserialize<'de> for Algorithm {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Algorithm {
|
||||
fn from(u: u32) -> Self {
|
||||
match u {
|
||||
1 => Algorithm::HOTP,
|
||||
2 => Algorithm::Steam,
|
||||
_ => Algorithm::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm {
|
||||
pub fn to_locale_string(&self) -> String {
|
||||
match *self {
|
||||
Algorithm::HOTP => gettext("HMAC-based"),
|
||||
Algorithm::TOTP => gettext("Time-based"),
|
||||
Algorithm::Steam => gettext("Steam"),
|
||||
Algorithm::SHA1 => gettext("SHA-1"),
|
||||
Algorithm::SHA256 => gettext("SHA-256"),
|
||||
Algorithm::SHA512 => gettext("SHA-512"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,10 +132,10 @@ impl FromStr for Algorithm {
|
|||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_ref() {
|
||||
"totp" | "otp" => Ok(Self::TOTP),
|
||||
"hotp" => Ok(Self::HOTP),
|
||||
"steam" => Ok(Self::Steam),
|
||||
_ => anyhow::bail!("Unsupported algorithm"),
|
||||
"sha1" | "otp" => Ok(Self::SHA1),
|
||||
"sha256" => Ok(Self::SHA256),
|
||||
"sha512" => Ok(Self::SHA512),
|
||||
_ => anyhow::bail!("Unsupported HMAC-algorithm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,89 +143,20 @@ impl FromStr for Algorithm {
|
|||
impl ToString for Algorithm {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
Algorithm::TOTP => "totp",
|
||||
Algorithm::HOTP => "hotp",
|
||||
Algorithm::Steam => "steam",
|
||||
Algorithm::SHA1 => "sha1",
|
||||
Algorithm::SHA256 => "sha256",
|
||||
Algorithm::SHA512 => "sha512",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, GEnum)]
|
||||
#[repr(u32)]
|
||||
#[genum(type_name = "ProviderHOTPAlgorithm")]
|
||||
pub enum HOTPAlgorithm {
|
||||
#[genum(name = "SHA1")]
|
||||
SHA1 = 0,
|
||||
#[genum(name = "SHA256")]
|
||||
SHA256 = 1,
|
||||
#[genum(name = "SHA512")]
|
||||
SHA512 = 2,
|
||||
}
|
||||
|
||||
impl Default for HOTPAlgorithm {
|
||||
fn default() -> Self {
|
||||
Self::SHA1
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for HOTPAlgorithm {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for HOTPAlgorithm {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(HOTPAlgorithm::from_str(&String::deserialize(deserializer)?).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl HOTPAlgorithm {
|
||||
pub fn to_locale_string(&self) -> String {
|
||||
match *self {
|
||||
HOTPAlgorithm::SHA1 => gettext("SHA1"),
|
||||
HOTPAlgorithm::SHA256 => gettext("SHA256"),
|
||||
HOTPAlgorithm::SHA512 => gettext("SHA512"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for HOTPAlgorithm {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_ref() {
|
||||
"sha1" | "otp" => Ok(Self::SHA1),
|
||||
"sha256" => Ok(Self::SHA256),
|
||||
"sha512" => Ok(Self::SHA512),
|
||||
_ => anyhow::bail!("Unsupported HMAC algorithm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for HOTPAlgorithm {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
HOTPAlgorithm::SHA1 => "sha1",
|
||||
HOTPAlgorithm::SHA256 => "sha256",
|
||||
HOTPAlgorithm::SHA512 => "sha512",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HOTPAlgorithm> for hmac::Algorithm {
|
||||
fn from(h: HOTPAlgorithm) -> Self {
|
||||
impl From<Algorithm> for hmac::Algorithm {
|
||||
fn from(h: Algorithm) -> Self {
|
||||
match h {
|
||||
HOTPAlgorithm::SHA1 => hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY,
|
||||
HOTPAlgorithm::SHA256 => hmac::HMAC_SHA256,
|
||||
HOTPAlgorithm::SHA512 => hmac::HMAC_SHA512,
|
||||
Algorithm::SHA1 => hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY,
|
||||
Algorithm::SHA256 => hmac::HMAC_SHA256,
|
||||
Algorithm::SHA512 => hmac::HMAC_SHA512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ mod providers;
|
|||
pub use self::account::Account;
|
||||
pub use self::account_sorter::AccountSorter;
|
||||
pub use self::accounts::AccountsModel;
|
||||
pub use self::algorithm::{Algorithm, HOTPAlgorithm};
|
||||
pub use self::algorithm::{Algorithm, OTPMethod};
|
||||
pub use self::favicon::{FaviconError, FaviconScrapper};
|
||||
pub use self::otp_uri::OtpUri;
|
||||
pub use self::otp_uri::OTPUri;
|
||||
pub use self::provider::Provider;
|
||||
pub use self::provider_sorter::ProviderSorter;
|
||||
pub use self::providers::ProvidersModel;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use crate::models::{Account, Algorithm, HOTPAlgorithm};
|
||||
use crate::models::{Account, Algorithm, OTPMethod};
|
||||
use percent_encoding::percent_decode_str;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OtpUri {
|
||||
pub struct OTPUri {
|
||||
pub algorithm: Algorithm,
|
||||
pub label: String,
|
||||
pub secret: String,
|
||||
pub issuer: String,
|
||||
pub hmac_algorithm: HOTPAlgorithm,
|
||||
pub method: OTPMethod,
|
||||
pub digits: Option<i32>,
|
||||
pub period: Option<i32>,
|
||||
pub counter: Option<i32>,
|
||||
}
|
||||
|
||||
impl FromStr for OtpUri {
|
||||
impl FromStr for OTPUri {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(uri: &str) -> Result<Self, Self::Err> {
|
||||
let url = url::Url::parse(uri)?;
|
||||
|
@ -26,11 +26,11 @@ impl FromStr for OtpUri {
|
|||
let mut counter = None;
|
||||
let mut digits = None;
|
||||
let mut provider_name = None;
|
||||
let mut hmac_algorithm = None;
|
||||
let mut algorithm = None;
|
||||
let mut secret = None;
|
||||
let pairs = url.query_pairs();
|
||||
|
||||
let algorithm = Algorithm::from_str(url.host_str().unwrap())?;
|
||||
let method = OTPMethod::from_str(url.host_str().unwrap())?;
|
||||
|
||||
let account_info = url
|
||||
.path()
|
||||
|
@ -60,7 +60,7 @@ impl FromStr for OtpUri {
|
|||
provider_name = Some(value.to_string());
|
||||
}
|
||||
"algorithm" => {
|
||||
hmac_algorithm = HOTPAlgorithm::from_str(&value).ok();
|
||||
algorithm = Algorithm::from_str(&value).ok();
|
||||
}
|
||||
"secret" => {
|
||||
secret = Some(value.to_string());
|
||||
|
@ -80,11 +80,11 @@ impl FromStr for OtpUri {
|
|||
};
|
||||
|
||||
Ok(Self {
|
||||
algorithm,
|
||||
method,
|
||||
label,
|
||||
secret: secret.unwrap(),
|
||||
issuer,
|
||||
hmac_algorithm: hmac_algorithm.unwrap_or_default(),
|
||||
algorithm: algorithm.unwrap_or_default(),
|
||||
digits,
|
||||
period,
|
||||
counter,
|
||||
|
@ -92,29 +92,29 @@ impl FromStr for OtpUri {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<String> for OtpUri {
|
||||
impl Into<String> for OTPUri {
|
||||
fn into(self) -> String {
|
||||
format!(
|
||||
"otpauth://{}/{}?secret={}&issuer={}&algorithm={}&digits={}&counter={}",
|
||||
self.algorithm.to_string(),
|
||||
self.method.to_string(),
|
||||
self.label,
|
||||
self.secret,
|
||||
self.issuer,
|
||||
self.hmac_algorithm.to_string(),
|
||||
self.algorithm.to_string(),
|
||||
self.digits.unwrap_or_else(|| 6),
|
||||
self.counter.unwrap_or_else(|| 1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Account> for OtpUri {
|
||||
impl From<&Account> for OTPUri {
|
||||
fn from(a: &Account) -> Self {
|
||||
Self {
|
||||
algorithm: a.provider().algorithm(),
|
||||
method: a.provider().method(),
|
||||
label: a.name(),
|
||||
secret: a.token(),
|
||||
issuer: a.provider().name(),
|
||||
hmac_algorithm: a.provider().hmac_algorithm(),
|
||||
algorithm: a.provider().algorithm(),
|
||||
digits: Some(a.provider().digits()),
|
||||
period: Some(a.provider().period()),
|
||||
counter: Some(a.counter()),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::algorithm::{Algorithm, HOTPAlgorithm};
|
||||
use super::algorithm::{Algorithm, OTPMethod};
|
||||
use crate::diesel::ExpressionMethods;
|
||||
use crate::models::{database, Account, AccountsModel, FaviconError, FaviconScrapper};
|
||||
use crate::schema::providers;
|
||||
|
@ -26,8 +26,8 @@ struct NewProvider {
|
|||
pub period: i32,
|
||||
pub digits: i32,
|
||||
pub default_counter: i32,
|
||||
pub hmac_algorithm: String,
|
||||
pub algorithm: String,
|
||||
pub method: String,
|
||||
}
|
||||
|
||||
#[derive(Identifiable, Queryable, Associations, Hash, PartialEq, Eq, Debug, Clone)]
|
||||
|
@ -41,17 +41,17 @@ pub struct DiProvider {
|
|||
pub period: i32,
|
||||
pub digits: i32,
|
||||
pub default_counter: i32,
|
||||
pub hmac_algorithm: String,
|
||||
pub algorithm: String,
|
||||
pub method: String,
|
||||
}
|
||||
|
||||
pub struct ProviderPriv {
|
||||
pub id: Cell<i32>,
|
||||
pub name: RefCell<String>,
|
||||
pub period: Cell<i32>,
|
||||
pub algorithm: RefCell<String>,
|
||||
pub method: RefCell<String>,
|
||||
pub default_counter: Cell<i32>,
|
||||
pub hmac_algorithm: RefCell<String>,
|
||||
pub algorithm: RefCell<String>,
|
||||
pub digits: Cell<i32>,
|
||||
pub website: RefCell<Option<String>>,
|
||||
pub help_url: RefCell<Option<String>>,
|
||||
|
@ -117,15 +117,6 @@ static PROPERTIES: [subclass::Property; 11] = [
|
|||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("hmac-algorithm", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"hmac_algorithm",
|
||||
"HMAC algorithm",
|
||||
Some(&HOTPAlgorithm::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("algorithm", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
|
@ -135,6 +126,15 @@ static PROPERTIES: [subclass::Property; 11] = [
|
|||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("method", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"method",
|
||||
"Method",
|
||||
Some(&OTPMethod::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("website", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
|
@ -182,13 +182,13 @@ impl ObjectSubclass for ProviderPriv {
|
|||
Self {
|
||||
id: Cell::new(0),
|
||||
default_counter: Cell::new(1),
|
||||
hmac_algorithm: RefCell::new(HOTPAlgorithm::default().to_string()),
|
||||
algorithm: RefCell::new(Algorithm::default().to_string()),
|
||||
digits: Cell::new(6),
|
||||
name: RefCell::new("".to_string()),
|
||||
website: RefCell::new(None),
|
||||
help_url: RefCell::new(None),
|
||||
image_uri: RefCell::new(None),
|
||||
algorithm: RefCell::new(Algorithm::default().to_string()),
|
||||
method: RefCell::new(OTPMethod::default().to_string()),
|
||||
period: Cell::new(30),
|
||||
filter_model: gtk::FilterListModel::new(Some(&model), gtk::NONE_FILTER),
|
||||
accounts: model,
|
||||
|
@ -221,12 +221,12 @@ impl ObjectImpl for ProviderPriv {
|
|||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.period.replace(period);
|
||||
}
|
||||
subclass::Property("algorithm", ..) => {
|
||||
let algorithm = value
|
||||
subclass::Property("method", ..) => {
|
||||
let method = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.algorithm.replace(algorithm);
|
||||
self.method.replace(method);
|
||||
}
|
||||
subclass::Property("digits", ..) => {
|
||||
let digits = value
|
||||
|
@ -234,12 +234,12 @@ impl ObjectImpl for ProviderPriv {
|
|||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.digits.replace(digits);
|
||||
}
|
||||
subclass::Property("hmac-algorithm", ..) => {
|
||||
let hmac_algorithm = value
|
||||
subclass::Property("algorithm", ..) => {
|
||||
let algorithm = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.hmac_algorithm.replace(hmac_algorithm);
|
||||
self.algorithm.replace(algorithm);
|
||||
}
|
||||
subclass::Property("default-counter", ..) => {
|
||||
let default_counter = value
|
||||
|
@ -276,9 +276,9 @@ impl ObjectImpl for ProviderPriv {
|
|||
subclass::Property("id", ..) => self.id.get().to_value(),
|
||||
subclass::Property("name", ..) => self.name.borrow().to_value(),
|
||||
subclass::Property("period", ..) => self.period.get().to_value(),
|
||||
subclass::Property("algorithm", ..) => self.algorithm.borrow().to_value(),
|
||||
subclass::Property("method", ..) => self.method.borrow().to_value(),
|
||||
subclass::Property("digits", ..) => self.digits.get().to_value(),
|
||||
subclass::Property("hmac-algorithm", ..) => self.hmac_algorithm.borrow().to_value(),
|
||||
subclass::Property("algorithm", ..) => self.algorithm.borrow().to_value(),
|
||||
subclass::Property("default-counter", ..) => self.default_counter.get().to_value(),
|
||||
subclass::Property("website", ..) => self.website.borrow().to_value(),
|
||||
subclass::Property("help-url", ..) => self.help_url.borrow().to_value(),
|
||||
|
@ -298,7 +298,7 @@ impl Provider {
|
|||
period: i32,
|
||||
algorithm: Algorithm,
|
||||
website: Option<String>,
|
||||
hmac_algorithm: HOTPAlgorithm,
|
||||
method: OTPMethod,
|
||||
digits: i32,
|
||||
default_counter: i32,
|
||||
) -> Result<Self> {
|
||||
|
@ -309,9 +309,9 @@ impl Provider {
|
|||
.values(NewProvider {
|
||||
name: name.to_string(),
|
||||
period,
|
||||
algorithm: algorithm.to_string(),
|
||||
method: method.to_string(),
|
||||
website,
|
||||
hmac_algorithm: hmac_algorithm.to_string(),
|
||||
algorithm: algorithm.to_string(),
|
||||
digits,
|
||||
default_counter,
|
||||
help_url: None,
|
||||
|
@ -355,8 +355,8 @@ impl Provider {
|
|||
id: i32,
|
||||
name: &str,
|
||||
period: i32,
|
||||
method: OTPMethod,
|
||||
algorithm: Algorithm,
|
||||
hmac_algorithm: HOTPAlgorithm,
|
||||
digits: i32,
|
||||
default_counter: i32,
|
||||
website: Option<String>,
|
||||
|
@ -372,8 +372,8 @@ impl Provider {
|
|||
("help-url", &help_url),
|
||||
("image-uri", &image_uri),
|
||||
("period", &period),
|
||||
("method", &method.to_string()),
|
||||
("algorithm", &algorithm.to_string()),
|
||||
("hmac-algorithm", &hmac_algorithm.to_string()),
|
||||
("digits", &digits),
|
||||
("default-counter", &default_counter),
|
||||
],
|
||||
|
@ -436,16 +436,16 @@ impl Provider {
|
|||
priv_.period.get()
|
||||
}
|
||||
|
||||
pub fn hmac_algorithm(&self) -> HOTPAlgorithm {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
HOTPAlgorithm::from_str(&priv_.hmac_algorithm.borrow().clone()).unwrap()
|
||||
}
|
||||
|
||||
pub fn algorithm(&self) -> Algorithm {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
Algorithm::from_str(&priv_.algorithm.borrow().clone()).unwrap()
|
||||
}
|
||||
|
||||
pub fn method(&self) -> OTPMethod {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
OTPMethod::from_str(&priv_.method.borrow().clone()).unwrap()
|
||||
}
|
||||
|
||||
pub fn website(&self) -> Option<String> {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.website.borrow().clone()
|
||||
|
@ -528,8 +528,8 @@ impl From<DiProvider> for Provider {
|
|||
p.id,
|
||||
&p.name,
|
||||
p.period,
|
||||
OTPMethod::from_str(&p.method).unwrap(),
|
||||
Algorithm::from_str(&p.algorithm).unwrap(),
|
||||
HOTPAlgorithm::from_str(&p.hmac_algorithm).unwrap(),
|
||||
p.digits,
|
||||
p.default_counter,
|
||||
p.website,
|
||||
|
@ -545,8 +545,8 @@ impl From<&Provider> for DiProvider {
|
|||
id: p.id(),
|
||||
name: p.name(),
|
||||
period: p.period(),
|
||||
method: p.method().to_string(),
|
||||
algorithm: p.algorithm().to_string(),
|
||||
hmac_algorithm: p.hmac_algorithm().to_string(),
|
||||
digits: p.digits(),
|
||||
default_counter: p.default_counter(),
|
||||
website: p.website(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{Account, Algorithm, HOTPAlgorithm, Provider};
|
||||
use super::{Account, Algorithm, OTPMethod, Provider};
|
||||
use anyhow::Result;
|
||||
use gio::prelude::*;
|
||||
use gio::subclass::ObjectSubclass;
|
||||
|
@ -68,9 +68,9 @@ impl ProvidersModel {
|
|||
&self,
|
||||
name: &str,
|
||||
period: i32,
|
||||
algorithm: Algorithm,
|
||||
method: OTPMethod,
|
||||
website: Option<String>,
|
||||
hmac_algorithm: HOTPAlgorithm,
|
||||
algorithm: Algorithm,
|
||||
digits: i32,
|
||||
default_counter: i32,
|
||||
) -> Result<Provider> {
|
||||
|
@ -82,7 +82,7 @@ impl ProvidersModel {
|
|||
period,
|
||||
algorithm,
|
||||
website,
|
||||
hmac_algorithm,
|
||||
method,
|
||||
digits,
|
||||
default_counter,
|
||||
)?;
|
||||
|
|
|
@ -18,8 +18,8 @@ table! {
|
|||
period -> Integer,
|
||||
digits -> Integer,
|
||||
default_counter -> Integer,
|
||||
hmac_algorithm -> Text,
|
||||
algorithm -> Text,
|
||||
method -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::helpers::qrcode;
|
||||
use crate::models::{Account, Algorithm, OtpUri, Provider, ProvidersModel};
|
||||
use crate::models::{Account, OTPMethod, OTPUri, Provider, ProvidersModel};
|
||||
use crate::widgets::{Action, ProviderImage, ProviderImageSize};
|
||||
use anyhow::Result;
|
||||
use gio::prelude::*;
|
||||
|
@ -45,8 +45,8 @@ mod imp {
|
|||
#[template_child(id = "provider_entry")]
|
||||
pub provider_entry: TemplateChild<gtk::Entry>,
|
||||
|
||||
#[template_child(id = "algorithm_label")]
|
||||
pub algorithm_label: TemplateChild<gtk::Label>,
|
||||
#[template_child(id = "method_label")]
|
||||
pub method_label: TemplateChild<gtk::Label>,
|
||||
|
||||
#[template_child(id = "provider_website_row")]
|
||||
pub provider_website_row: TemplateChild<libhandy::ActionRow>,
|
||||
|
@ -54,8 +54,8 @@ mod imp {
|
|||
#[template_child(id = "provider_help_row")]
|
||||
pub provider_help_row: TemplateChild<libhandy::ActionRow>,
|
||||
|
||||
#[template_child(id = "hmac_algorithm_row")]
|
||||
pub hmac_algorithm_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child(id = "algorithm_label")]
|
||||
pub algorithm_label: TemplateChild<gtk::Label>,
|
||||
|
||||
#[template_child(id = "counter_row")]
|
||||
pub counter_row: TemplateChild<libhandy::ActionRow>,
|
||||
|
@ -92,11 +92,11 @@ mod imp {
|
|||
period_label: TemplateChild::default(),
|
||||
digits_label: TemplateChild::default(),
|
||||
provider_entry: TemplateChild::default(),
|
||||
algorithm_label: TemplateChild::default(),
|
||||
method_label: TemplateChild::default(),
|
||||
provider_website_row: TemplateChild::default(),
|
||||
provider_help_row: TemplateChild::default(),
|
||||
provider_completion: TemplateChild::default(),
|
||||
hmac_algorithm_row: TemplateChild::default(),
|
||||
algorithm_label: TemplateChild::default(),
|
||||
counter_row: TemplateChild::default(),
|
||||
period_row: TemplateChild::default(),
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ impl AccountAddDialog {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn set_from_otp_uri(&self, otp_uri: OtpUri) {
|
||||
fn set_from_otp_uri(&self, otp_uri: OTPUri) {
|
||||
let self_ = imp::AccountAddDialog::from_instance(self);
|
||||
|
||||
self_.token_entry.get().set_text(&otp_uri.secret);
|
||||
|
@ -194,9 +194,9 @@ impl AccountAddDialog {
|
|||
.find_or_create(
|
||||
&otp_uri.issuer,
|
||||
otp_uri.period.unwrap_or_else(|| 30),
|
||||
otp_uri.algorithm,
|
||||
otp_uri.method,
|
||||
None,
|
||||
otp_uri.hmac_algorithm,
|
||||
otp_uri.algorithm,
|
||||
otp_uri.digits.unwrap_or_else(|| 6),
|
||||
otp_uri.counter.unwrap_or_else(|| 1),
|
||||
)
|
||||
|
@ -233,6 +233,11 @@ impl AccountAddDialog {
|
|||
|
||||
self_.image.set_provider(&provider);
|
||||
|
||||
self_
|
||||
.method_label
|
||||
.get()
|
||||
.set_text(&provider.method().to_locale_string());
|
||||
|
||||
self_
|
||||
.algorithm_label
|
||||
.get()
|
||||
|
@ -243,18 +248,16 @@ impl AccountAddDialog {
|
|||
.get()
|
||||
.set_text(&provider.digits().to_string());
|
||||
|
||||
match provider.algorithm() {
|
||||
Algorithm::TOTP => {
|
||||
self_.hmac_algorithm_row.get().hide();
|
||||
match provider.method() {
|
||||
OTPMethod::TOTP => {
|
||||
self_.counter_row.get().hide();
|
||||
self_.period_row.get().show();
|
||||
}
|
||||
Algorithm::HOTP => {
|
||||
self_.hmac_algorithm_row.get().show();
|
||||
OTPMethod::HOTP => {
|
||||
self_.counter_row.get().show();
|
||||
self_.period_row.get().hide();
|
||||
}
|
||||
Algorithm::Steam => {}
|
||||
OTPMethod::Steam => {}
|
||||
};
|
||||
|
||||
if let Some(ref website) = provider.website() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::models::{Algorithm, HOTPAlgorithm, Provider};
|
||||
use crate::models::{Algorithm, OTPMethod, Provider};
|
||||
use crate::widgets::{ProviderImage, ProviderImageSize};
|
||||
use gio::subclass::ObjectSubclass;
|
||||
use glib::subclass::prelude::*;
|
||||
|
@ -13,6 +13,8 @@ pub enum ProviderPageMode {
|
|||
}
|
||||
|
||||
mod imp {
|
||||
use crate::models::OTPMethod;
|
||||
|
||||
use super::*;
|
||||
use glib::subclass;
|
||||
use gtk::subclass::prelude::*;
|
||||
|
@ -34,10 +36,10 @@ mod imp {
|
|||
pub provider_website_entry: TemplateChild<gtk::Entry>,
|
||||
#[template_child(id = "provider_help_entry")]
|
||||
pub provider_help_entry: TemplateChild<gtk::Entry>,
|
||||
#[template_child(id = "method_comborow")]
|
||||
pub method_comborow: TemplateChild<libhandy::ComboRow>,
|
||||
#[template_child(id = "algorithm_comborow")]
|
||||
pub algorithm_comborow: TemplateChild<libhandy::ComboRow>,
|
||||
#[template_child(id = "hmac_algorithm_comborow")]
|
||||
pub hmac_algorithm_comborow: TemplateChild<libhandy::ComboRow>,
|
||||
#[template_child(id = "period_row")]
|
||||
pub period_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child(id = "digits_row")]
|
||||
|
@ -46,8 +48,8 @@ mod imp {
|
|||
pub default_counter_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child(id = "title")]
|
||||
pub title: TemplateChild<gtk::Label>,
|
||||
pub methods_model: libhandy::EnumListModel,
|
||||
pub algorithms_model: libhandy::EnumListModel,
|
||||
pub hmac_algorithms_model: libhandy::EnumListModel,
|
||||
}
|
||||
|
||||
impl ObjectSubclass for ProviderPage {
|
||||
|
@ -60,8 +62,8 @@ mod imp {
|
|||
glib_object_subclass!();
|
||||
|
||||
fn new() -> Self {
|
||||
let methods_model = libhandy::EnumListModel::new(OTPMethod::static_type());
|
||||
let algorithms_model = libhandy::EnumListModel::new(Algorithm::static_type());
|
||||
let hmac_algorithms_model = libhandy::EnumListModel::new(HOTPAlgorithm::static_type());
|
||||
|
||||
Self {
|
||||
image: ProviderImage::new(ProviderImageSize::Large),
|
||||
|
@ -72,14 +74,14 @@ mod imp {
|
|||
default_counter_spinbutton: TemplateChild::default(),
|
||||
provider_website_entry: TemplateChild::default(),
|
||||
provider_help_entry: TemplateChild::default(),
|
||||
method_comborow: TemplateChild::default(),
|
||||
algorithm_comborow: TemplateChild::default(),
|
||||
hmac_algorithm_comborow: TemplateChild::default(),
|
||||
period_row: TemplateChild::default(),
|
||||
digits_row: TemplateChild::default(),
|
||||
default_counter_row: TemplateChild::default(),
|
||||
title: TemplateChild::default(),
|
||||
methods_model,
|
||||
algorithms_model,
|
||||
hmac_algorithms_model,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,10 +145,10 @@ impl ProviderPage {
|
|||
.get()
|
||||
.set_value(provider.digits() as f64);
|
||||
|
||||
self_.hmac_algorithm_comborow.get().set_selected(
|
||||
self_.method_comborow.get().set_selected(
|
||||
self_
|
||||
.hmac_algorithms_model
|
||||
.find_position(provider.hmac_algorithm().to_glib()),
|
||||
.methods_model
|
||||
.find_position(provider.method().to_glib()),
|
||||
);
|
||||
self_.image.set_provider(&provider);
|
||||
self_
|
||||
|
@ -171,27 +173,25 @@ impl ProviderPage {
|
|||
page.on_algorithm_changed();
|
||||
}));
|
||||
self_
|
||||
.hmac_algorithm_comborow
|
||||
.method_comborow
|
||||
.get()
|
||||
.set_model(Some(&self_.hmac_algorithms_model));
|
||||
.set_model(Some(&self_.methods_model));
|
||||
}
|
||||
|
||||
fn on_algorithm_changed(&self) {
|
||||
let self_ = imp::ProviderPage::from_instance(self);
|
||||
|
||||
let selected = Algorithm::from(self_.algorithm_comborow.get().get_selected());
|
||||
let selected = OTPMethod::from(self_.method_comborow.get().get_selected());
|
||||
match selected {
|
||||
Algorithm::TOTP => {
|
||||
OTPMethod::TOTP => {
|
||||
self_.default_counter_row.get().hide();
|
||||
self_.hmac_algorithm_comborow.get().hide();
|
||||
self_.period_row.get().show();
|
||||
}
|
||||
Algorithm::HOTP => {
|
||||
OTPMethod::HOTP => {
|
||||
self_.default_counter_row.get().show();
|
||||
self_.hmac_algorithm_comborow.get().show();
|
||||
self_.period_row.get().hide();
|
||||
}
|
||||
Algorithm::Steam => {}
|
||||
OTPMethod::Steam => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ impl ProviderPage {
|
|||
self_.provider_website_entry.get().set_text("");
|
||||
self_.provider_help_entry.get().set_text("");
|
||||
|
||||
self_.algorithm_comborow.get().set_selected(0);
|
||||
self_.method_comborow.get().set_selected(0);
|
||||
}
|
||||
ProviderPageMode::Edit => {}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::models::{Account, AccountSorter, Algorithm, Provider};
|
||||
use crate::models::{Account, AccountSorter, OTPMethod, Provider};
|
||||
use crate::widgets::{accounts::AccountRow, ProviderImage, ProviderImageSize};
|
||||
use gio::prelude::*;
|
||||
use gio::subclass::ObjectSubclass;
|
||||
|
@ -122,13 +122,13 @@ impl ProviderRow {
|
|||
fn setup_widgets(&self) {
|
||||
let self_ = imp::ProviderRow::from_instance(self);
|
||||
|
||||
self.add_css_class(&self.provider().algorithm().to_string());
|
||||
self.add_css_class(&self.provider().method().to_string());
|
||||
|
||||
self_.header.get().prepend(&self_.image);
|
||||
self_.image.set_provider(&self.provider());
|
||||
|
||||
let progress_bar = self_.progress.get();
|
||||
if self.provider().algorithm() == Algorithm::TOTP {
|
||||
if self.provider().method() == OTPMethod::TOTP {
|
||||
progress_bar.set_fraction(1_f64);
|
||||
let max = self.provider().period() as f64;
|
||||
glib::timeout_add_local(
|
||||
|
|
Loading…
Add table
Reference in a new issue