mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 08:44:40 +01:00
OTPUri: Fix encoding when generating a URI
Also add some basic tests for now Fixes #363
This commit is contained in:
parent
d4810bb6f9
commit
4bb81c3cee
2 changed files with 67 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
|||
use std::{fmt::Write, str::FromStr};
|
||||
|
||||
use percent_encoding::percent_decode_str;
|
||||
use percent_encoding::{percent_decode_str, utf8_percent_encode, NON_ALPHANUMERIC};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
|
@ -11,14 +11,14 @@ use crate::{
|
|||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OTPUri {
|
||||
pub algorithm: Algorithm,
|
||||
pub label: String,
|
||||
pub secret: String,
|
||||
pub issuer: String,
|
||||
pub method: Method,
|
||||
pub digits: Option<u32>,
|
||||
pub period: Option<u32>,
|
||||
pub counter: Option<u32>,
|
||||
pub(crate) algorithm: Algorithm,
|
||||
pub(crate) label: String,
|
||||
pub(crate) secret: String,
|
||||
pub(crate) issuer: String,
|
||||
pub(crate) method: Method,
|
||||
pub(crate) digits: Option<u32>,
|
||||
pub(crate) period: Option<u32>,
|
||||
pub(crate) counter: Option<u32>,
|
||||
}
|
||||
|
||||
impl RestorableItem for OTPUri {
|
||||
|
@ -149,9 +149,9 @@ impl From<OTPUri> for String {
|
|||
let mut otp_uri = format!(
|
||||
"otpauth://{}/{}?secret={}&issuer={}&algorithm={}",
|
||||
val.method.to_string(),
|
||||
val.label,
|
||||
utf8_percent_encode(&val.label, NON_ALPHANUMERIC).to_string(),
|
||||
val.secret,
|
||||
val.issuer,
|
||||
utf8_percent_encode(&val.issuer, NON_ALPHANUMERIC).to_string(),
|
||||
val.algorithm.to_string(),
|
||||
);
|
||||
if let Some(digits) = val.digits {
|
||||
|
@ -190,3 +190,50 @@ impl From<&Account> for OTPUri {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::OTPUri;
|
||||
use crate::{
|
||||
backup::RestorableItem,
|
||||
models::{Algorithm, Method},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn uri_decode() {
|
||||
let uri = OTPUri::from_str(
|
||||
"otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(uri.method(), Method::TOTP);
|
||||
assert_eq!(uri.issuer(), "Example");
|
||||
assert_eq!(uri.secret(), "JBSWY3DPEHPK3PXP");
|
||||
assert_eq!(uri.account(), "alice@google.com");
|
||||
|
||||
let uri = OTPUri::from_str("otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30").unwrap();
|
||||
assert_eq!(uri.period(), Some(30));
|
||||
assert_eq!(uri.digits(), Some(6));
|
||||
assert_eq!(uri.algorithm(), Algorithm::SHA1);
|
||||
assert_eq!(uri.issuer(), "ACME Co");
|
||||
assert_eq!(uri.secret(), "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ");
|
||||
assert_eq!(uri.account(), "john.doe@email.com");
|
||||
assert_eq!(uri.method(), Method::TOTP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uri_encode() {
|
||||
let uri = OTPUri {
|
||||
algorithm: Algorithm::SHA1,
|
||||
label: "account test".to_owned(),
|
||||
secret: "dznF36H0IIg17rK".to_owned(),
|
||||
issuer: "Test".to_owned(),
|
||||
method: Method::TOTP,
|
||||
digits: Some(6),
|
||||
period: Some(30),
|
||||
counter: None,
|
||||
};
|
||||
assert_eq!(String::from(uri), "otpauth://totp/account%20test?secret=dznF36H0IIg17rK&issuer=Test&algorithm=sha1&digits=6&period=30");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use gtk::{glib, prelude::*, subclass::prelude::*};
|
|||
use once_cell::sync::{Lazy, OnceCell};
|
||||
|
||||
use crate::{
|
||||
backup::RestorableItem,
|
||||
models::{otp, Account, OTPUri, Provider, ProvidersModel},
|
||||
widgets::{providers::ProviderPage, Camera, ErrorRevealer, ProviderImage, UrlRow},
|
||||
};
|
||||
|
@ -250,19 +251,19 @@ impl AccountAddDialog {
|
|||
let imp = self.imp();
|
||||
imp.deck.set_visible_child_name("main"); // Switch back the form view
|
||||
|
||||
imp.token_entry.set_text(&otp_uri.secret);
|
||||
imp.username_entry.set_text(&otp_uri.label);
|
||||
imp.token_entry.set_text(&otp_uri.secret());
|
||||
imp.username_entry.set_text(&otp_uri.account());
|
||||
|
||||
let provider = self
|
||||
.model()
|
||||
.find_or_create(
|
||||
&otp_uri.issuer,
|
||||
otp_uri.period,
|
||||
otp_uri.method,
|
||||
&otp_uri.issuer(),
|
||||
otp_uri.period(),
|
||||
otp_uri.method(),
|
||||
None,
|
||||
otp_uri.algorithm,
|
||||
otp_uri.digits,
|
||||
otp_uri.counter,
|
||||
otp_uri.algorithm(),
|
||||
otp_uri.digits(),
|
||||
otp_uri.counter(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue