Cache TOTP discovery and report progress (#74)
This commit is contained in:
1 parent
6edcb5fc86
commit
9759162eff
12 files changed
+1577
-198
No files matched your search
@@ -19,7 +19,10 @@ use crate::{
|
||||
MobileMutationAction, MobileMutationError, MobileMutationOutcome, MobileMutationPlan,
|
||||
MobileMutationRequest, MobileMutationService,
|
||||
},
|
||||
mobile_totp::{MobileTotpDetail, MobileTotpError, MobileTotpPage, MobileTotpService},
|
||||
mobile_totp::{
|
||||
MobileTotpDetail, MobileTotpError, MobileTotpOperation, MobileTotpPage, MobileTotpService,
|
||||
},
|
||||
otp::OtpError,
|
||||
recipient::RecipientPolicyManager,
|
||||
repository::{
|
||||
DirectoryPath, EncryptedEntry, EntryPath, Repository, RepositoryError, SecretBytes,
|
||||
@@ -177,6 +180,7 @@ pub struct MobileAuthentication {
|
||||
keys: KeyStore,
|
||||
session: NativeAuthenticationSession,
|
||||
status: Mutex<MobileAuthenticationStatus>,
|
||||
totp_discovery: Mutex<()>,
|
||||
}
|
||||
|
||||
impl MobileAuthentication {
|
||||
@@ -208,6 +212,7 @@ impl MobileAuthentication {
|
||||
repository,
|
||||
keys,
|
||||
session,
|
||||
totp_discovery: Mutex::new(()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -481,8 +486,17 @@ impl MobileAuthentication {
|
||||
self.unlock_ciphertext(&ciphertext, passphrase)
|
||||
}
|
||||
|
||||
pub fn totp_page(&self) -> Result<MobileTotpPage, MobileAuthenticationError> {
|
||||
pub fn totp_page(
|
||||
&self,
|
||||
operation: &MobileTotpOperation,
|
||||
) -> Result<MobileTotpPage, MobileAuthenticationError> {
|
||||
self.ensure_active()?;
|
||||
let _discovery = self.totp_discovery.lock().map_err(|_| {
|
||||
entry_detail(
|
||||
"TOTP Discovery Is Unavailable",
|
||||
"the TOTP discovery lock is unavailable",
|
||||
)
|
||||
})?;
|
||||
let (handle, key, shared) = {
|
||||
let status = self.status()?;
|
||||
let active = status.active.as_ref().ok_or_else(locked_error)?;
|
||||
@@ -492,12 +506,19 @@ impl MobileAuthentication {
|
||||
status.watch_shared_totp_entries.clone(),
|
||||
)
|
||||
};
|
||||
let cache_path = self.config.source().with_file_name("totp-catalog.toml");
|
||||
let mut provider = KeyOnlyProvider::new(handle, &key);
|
||||
MobileTotpService::new(&self.repository, &self.keys)
|
||||
.page(&shared, &mut provider)
|
||||
.discover(&shared, &mut provider, &cache_path, operation)
|
||||
.map_err(totp_error)
|
||||
}
|
||||
|
||||
pub fn cached_totp_page(&self) -> Result<Option<MobileTotpPage>, MobileAuthenticationError> {
|
||||
let shared = self.status()?.watch_shared_totp_entries.clone();
|
||||
let cache_path = self.config.source().with_file_name("totp-catalog.toml");
|
||||
Ok(MobileTotpService::new(&self.repository, &self.keys).cached_page(&shared, &cache_path))
|
||||
}
|
||||
|
||||
pub fn totp_detail(
|
||||
&self,
|
||||
path: &str,
|
||||
@@ -1043,7 +1064,19 @@ fn editor_error(error: MobileEntryEditorError) -> MobileAuthenticationError {
|
||||
}
|
||||
|
||||
fn totp_error(error: MobileTotpError) -> MobileAuthenticationError {
|
||||
entry_detail("TOTP Is Unavailable", error)
|
||||
match error {
|
||||
MobileTotpError::Otp(OtpError::Cancelled) => MobileAuthenticationError::new(
|
||||
MobileAuthenticationErrorKind::Cancelled,
|
||||
"TOTP Discovery Cancelled",
|
||||
"TOTP discovery was cancelled",
|
||||
),
|
||||
MobileTotpError::ConcurrentModification => MobileAuthenticationError::new(
|
||||
MobileAuthenticationErrorKind::Conflict,
|
||||
"TOTP Discovery Needs Refreshing",
|
||||
"the password store changed while TOTP discovery was in progress",
|
||||
),
|
||||
error => entry_detail("TOTP Is Unavailable", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn editor_missing() -> MobileAuthenticationError {
|
||||
|
||||
Reference in new issue
Block a user