diff --git a/Cargo.lock b/Cargo.lock index 7961750487..a77763edc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4912,7 +4912,6 @@ dependencies = [ "tokio-util", "tracing", "urn", - "uuid", ] [[package]] diff --git a/crates/account/src/error.rs b/crates/account/src/error.rs index d278b381ac..0362c0ae4a 100644 --- a/crates/account/src/error.rs +++ b/crates/account/src/error.rs @@ -10,11 +10,6 @@ pub enum Error { #[error("could not find folder password for '{0}'")] NoFolderPassword(VaultId), - /// Error generated accessing an account that is not - /// authenticated. - #[error("account not authenticated, sign in required")] - NotAuthenticated, - /// Error generated when a database is required. #[error("database client is required")] NoDatabase, @@ -77,6 +72,10 @@ pub enum Error { #[error(transparent)] Core(#[from] sos_core::Error), + /// Authentication errors. + #[error(transparent)] + Authentication(#[from] sos_core::AuthenticationError), + #[cfg(feature = "search")] /// Error generated by the search library. #[error(transparent)] diff --git a/crates/account/src/local_account.rs b/crates/account/src/local_account.rs index dc2727f05c..f3fe8b08a6 100644 --- a/crates/account/src/local_account.rs +++ b/crates/account/src/local_account.rs @@ -28,8 +28,8 @@ use sos_core::{ AccountEvent, DeviceEvent, Event, EventKind, EventLog, EventRecord, ReadEvent, WriteEvent, }, - AccountId, AccountRef, FolderRef, Paths, SecretId, UtcDateTime, - VaultCommit, VaultId, + AccountId, AccountRef, AuthenticationError, FolderRef, Paths, SecretId, + UtcDateTime, VaultCommit, VaultId, }; use sos_login::{ device::{DeviceManager, DeviceSigner}, @@ -110,7 +110,7 @@ impl LocalAccount { fn ensure_authenticated(&self) -> Result<()> { let is_authenticated = self.storage.is_authenticated(); if !is_authenticated { - return Err(Error::NotAuthenticated); + return Err(AuthenticationError::NotAuthenticated.into()); } Ok(()) } diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index 2d4da60a35..f5572f2697 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -54,7 +54,6 @@ futures.workspace = true tokio.workspace = true tokio-util.workspace = true binary-stream.workspace = true -uuid.workspace = true tracing.workspace = true indexmap.workspace = true tempfile.workspace = true diff --git a/crates/backend/src/error.rs b/crates/backend/src/error.rs index 9006195d78..78e37f9fa0 100644 --- a/crates/backend/src/error.rs +++ b/crates/backend/src/error.rs @@ -1,5 +1,4 @@ use thiserror::Error; -use uuid::Uuid; /// Errors generated by the library. #[derive(Debug, Error)] @@ -44,10 +43,5 @@ pub enum Error { SystemMessages(#[from] sos_system_messages::Error), } -/// Generic storage error shared between the client and server. -#[derive(Debug, Error)] -pub enum StorageError { - /// Error generated attempting to access a vault that is not available. - #[error("cache not available for {0}")] - CacheNotAvailable(Uuid), -} +// Backwards compatible +pub use sos_core::StorageError; diff --git a/crates/core/src/error.rs b/crates/core/src/error.rs index e53bc99134..1977e50e9a 100644 --- a/crates/core/src/error.rs +++ b/crates/core/src/error.rs @@ -1,6 +1,8 @@ //! Errors generated by the core library. use thiserror::Error; +use crate::VaultId; + /// Error thrown by the core library. #[derive(Debug, Error)] pub enum Error { @@ -148,3 +150,21 @@ pub trait ErrorExt { /// Whether this is a permission denied error. fn is_permission_denied(&self) -> bool; } + +/// Generic storage error shared between the client and server. +#[derive(Debug, Error)] +pub enum StorageError { + /// Error generated attempting to access a folder + /// that is not available in-memory. + #[error("cache not available for {0}")] + CacheNotAvailable(VaultId), +} + +/// Authentication errors. +#[derive(Debug, Error)] +pub enum AuthenticationError { + /// Error generated accessing an account that is not + /// authenticated when authentication is required. + #[error("account not authenticated, sign in required")] + NotAuthenticated, +} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 019bbdd915..65f80f455b 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -23,7 +23,7 @@ pub use account::AccountId; pub use date_time::UtcDateTime; // pub use device::{DevicePublicKey, TrustedDevice}; pub use encoding::{decode, encode}; -pub use error::{Error, ErrorExt}; +pub use error::{AuthenticationError, Error, ErrorExt, StorageError}; pub use file::{ExternalFile, ExternalFileName}; pub use identity::{AccountRef, PublicIdentity}; pub use origin::{Origin, RemoteOrigins}; diff --git a/crates/login/src/error.rs b/crates/login/src/error.rs index 57a970d165..28a0073e2a 100644 --- a/crates/login/src/error.rs +++ b/crates/login/src/error.rs @@ -13,11 +13,6 @@ pub enum Error { #[error("could not find account {0}")] NoAccount(String), - /// Error generated accessing an account that is not - /// authenticated. - #[error("account not authenticated, sign in required")] - NotAuthenticated, - /// Error generated when a folder password could not be located. #[error("could not find folder password for '{0}'")] NoFolderPassword(VaultId), @@ -69,6 +64,10 @@ pub enum Error { #[error(transparent)] Core(#[from] sos_core::Error), + /// Authentication errors. + #[error(transparent)] + Authentication(#[from] sos_core::AuthenticationError), + /// Error generated by the backend library. #[error(transparent)] Backend(#[from] sos_backend::Error), diff --git a/crates/login/src/identity.rs b/crates/login/src/identity.rs index ba0ee3842e..fb579fa042 100644 --- a/crates/login/src/identity.rs +++ b/crates/login/src/identity.rs @@ -11,8 +11,8 @@ use crate::{ use secrecy::SecretString; use sos_backend::{database::async_sqlite::Client, BackendTarget}; use sos_core::{ - crypto::AccessKey, decode, events::Event, AccountId, Paths, SecretId, - VaultId, + crypto::AccessKey, decode, events::Event, AccountId, AuthenticationError, + Paths, SecretId, VaultId, }; use sos_vault::{list_local_folders, read_public_identity, Summary, Vault}; use sos_vfs as vfs; @@ -81,29 +81,42 @@ impl Identity { /// Device manager. pub fn devices(&self) -> Result<&DeviceManager> { - self.identity + Ok(self + .identity .as_ref() - .ok_or(Error::NotAuthenticated)? - .devices() + .ok_or(AuthenticationError::NotAuthenticated)? + .devices()?) } /// Account information. pub fn account(&self) -> Result<&PublicIdentity> { - self.account.as_ref().ok_or(Error::NotAuthenticated) + Ok(self + .account + .as_ref() + .ok_or(AuthenticationError::NotAuthenticated)?) } fn account_mut(&mut self) -> Result<&mut PublicIdentity> { - self.account.as_mut().ok_or(Error::NotAuthenticated) + Ok(self + .account + .as_mut() + .ok_or(AuthenticationError::NotAuthenticated)?) } /// Private identity. pub fn identity(&self) -> Result<&IdentityFolder> { - self.identity.as_ref().ok_or(Error::NotAuthenticated) + Ok(self + .identity + .as_ref() + .ok_or(AuthenticationError::NotAuthenticated)?) } #[doc(hidden)] pub fn identity_mut(&mut self) -> Result<&mut IdentityFolder> { - self.identity.as_mut().ok_or(Error::NotAuthenticated) + Ok(self + .identity + .as_mut() + .ok_or(AuthenticationError::NotAuthenticated)?) } /// Verify the access key for this account. diff --git a/crates/login/src/identity_folder.rs b/crates/login/src/identity_folder.rs index 5a26304ea7..b21a1e3f20 100644 --- a/crates/login/src/identity_folder.rs +++ b/crates/login/src/identity_folder.rs @@ -18,7 +18,7 @@ use sos_backend::{ }; use sos_core::{ constants::LOGIN_AGE_KEY_URN, crypto::AccessKey, decode, encode, - AccountId, Paths, + AccountId, AuthenticationError, Paths, }; use sos_password::diceware::generate_passphrase_words; use sos_signer::ed25519; @@ -108,7 +108,10 @@ impl IdentityFolder { /// Device manager. pub fn devices(&self) -> Result<&DeviceManager> { - self.devices.as_ref().ok_or(Error::NotAuthenticated) + Ok(self + .devices + .as_ref() + .ok_or(AuthenticationError::NotAuthenticated)?) } /// Rename this identity vault. diff --git a/crates/net/src/account/network_account.rs b/crates/net/src/account/network_account.rs index 540da698d3..f98e398ad3 100644 --- a/crates/net/src/account/network_account.rs +++ b/crates/net/src/account/network_account.rs @@ -18,8 +18,8 @@ use sos_core::{ AccountEvent, DeviceEvent, EventLog, EventLogType, EventRecord, ReadEvent, WriteEvent, }, - AccountId, AccountRef, FolderRef, Origin, Paths, PublicIdentity, - RemoteOrigins, SecretId, UtcDateTime, VaultId, + AccountId, AccountRef, AuthenticationError, FolderRef, Origin, Paths, + PublicIdentity, RemoteOrigins, SecretId, UtcDateTime, VaultId, }; use sos_login::device::{DeviceManager, DeviceSigner}; use sos_protocol::{ @@ -460,7 +460,7 @@ impl NetworkAccount { #[cfg(feature = "files")] async fn start_file_transfers(&mut self) -> Result<()> { if !self.is_authenticated().await { - return Err(sos_account::Error::NotAuthenticated.into()); + return Err(AuthenticationError::NotAuthenticated.into()); } if self.offline { @@ -634,7 +634,7 @@ impl NetworkAccount { .file_transfers .as_ref() .map(|t| Arc::clone(&t.inflight)) - .ok_or_else(|| sos_account::Error::NotAuthenticated)?) + .ok_or_else(|| AuthenticationError::NotAuthenticated)?) } /// Convert file mutation events into file transfer queue entries. diff --git a/crates/net/src/error.rs b/crates/net/src/error.rs index dd4af3c5bb..c0e90275aa 100644 --- a/crates/net/src/error.rs +++ b/crates/net/src/error.rs @@ -75,6 +75,10 @@ pub enum Error { #[error(transparent)] Core(#[from] sos_core::Error), + /// Authentication errors. + #[error(transparent)] + Authentication(#[from] sos_core::AuthenticationError), + /// Error generated by the backend library. #[error(transparent)] Backend(#[from] sos_backend::Error), diff --git a/crates/storage/client/src/error.rs b/crates/storage/client/src/error.rs index 3359963389..ca1900091f 100644 --- a/crates/storage/client/src/error.rs +++ b/crates/storage/client/src/error.rs @@ -5,11 +5,6 @@ use thiserror::Error; /// Errors generated by the client storage library. #[derive(Debug, Error)] pub enum Error { - /// Error generated accessing an account that is not - /// authenticated. - #[error("account not authenticated, sign in required")] - NotAuthenticated, - /// Error generated attempting to make changes to the current /// vault but no vault is open. #[error("no vault is available, vault must be open")] @@ -64,6 +59,10 @@ pub enum Error { #[error(transparent)] Core(#[from] sos_core::Error), + /// Authentication errors. + #[error(transparent)] + Authentication(#[from] sos_core::AuthenticationError), + #[cfg(feature = "search")] /// Errors generated by the search library. #[error(transparent)] diff --git a/crates/storage/client/src/filesystem/mod.rs b/crates/storage/client/src/filesystem/mod.rs index d11744af05..7560599746 100644 --- a/crates/storage/client/src/filesystem/mod.rs +++ b/crates/storage/client/src/filesystem/mod.rs @@ -24,7 +24,7 @@ use sos_core::{ patch::FolderPatch, AccountEvent, Event, EventLog, EventRecord, ReadEvent, WriteEvent, }, - AccountId, FolderRef, Paths, UtcDateTime, + AccountId, AuthenticationError, FolderRef, Paths, UtcDateTime, }; use sos_login::{FolderKeys, Identity}; use sos_password::diceware::generate_passphrase; @@ -1417,11 +1417,17 @@ impl ClientAccountStorage for ClientFileSystemStorage { } fn authenticated_user(&self) -> Result<&Identity> { - self.authenticated.as_ref().ok_or(Error::NotAuthenticated) + Ok(self + .authenticated + .as_ref() + .ok_or(AuthenticationError::NotAuthenticated)?) } fn authenticated_user_mut(&mut self) -> Result<&mut Identity> { - self.authenticated.as_mut().ok_or(Error::NotAuthenticated) + Ok(self + .authenticated + .as_mut() + .ok_or(AuthenticationError::NotAuthenticated)?) } fn is_authenticated(&self) -> bool { @@ -1445,7 +1451,9 @@ impl ClientAccountStorage for ClientFileSystemStorage { &mut self, vault: Vault, ) -> Result { - self.authenticated.as_ref().ok_or(Error::NotAuthenticated)?; + self.authenticated + .as_ref() + .ok_or(AuthenticationError::NotAuthenticated)?; // Update the identity vault let buffer = encode(&vault).await?; diff --git a/crates/vault/src/vault.rs b/crates/vault/src/vault.rs index 650584cd3b..e91de940af 100644 --- a/crates/vault/src/vault.rs +++ b/crates/vault/src/vault.rs @@ -22,7 +22,6 @@ use sos_vfs::File; use std::io::Cursor; use std::{ borrow::Cow, cmp::Ordering, collections::HashMap, fmt, path::Path, - str::FromStr, }; use tokio::io::{AsyncReadExt, AsyncSeek, BufReader}; use typeshare::typeshare;