From 4086c0c9a6e62b79e193791d74f15c5b224f18a6 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Fri, 3 Oct 2025 23:37:32 -0400 Subject: [PATCH] Remove sync15's "standalone-sync" feature, remove UDL for a single enum. Remove the udl for sync15 - it just had one enum. "Bonus" update of the crate to 2024, which is a bigger diff than I anticipated. Seems ok though? --- components/logins/Cargo.toml | 4 +- components/logins/src/error.rs | 25 --- components/logins/src/logins.udl | 4 - components/logins/src/schema.rs | 9 +- components/logins/src/sync/engine.rs | 15 -- components/places/Cargo.toml | 4 +- .../appservices/places/PlacesConnection.kt | 72 ------- components/places/src/api/places_api.rs | 204 +----------------- .../places/src/bookmark_sync/incoming.rs | 4 +- components/places/src/error.rs | 24 --- components/places/src/ffi.rs | 50 ----- components/places/src/places.udl | 12 -- components/sync15/Cargo.toml | 34 +-- components/sync15/build.rs | 7 - components/sync15/src/bso/content.rs | 5 +- components/sync15/src/bso/crypto.rs | 4 +- components/sync15/src/client/coll_state.rs | 8 +- components/sync15/src/client/coll_update.rs | 2 +- components/sync15/src/client/mod.rs | 4 +- components/sync15/src/client/request.rs | 10 +- components/sync15/src/client/state.rs | 25 ++- components/sync15/src/client/status.rs | 10 +- .../sync15/src/client/storage_client.rs | 10 +- components/sync15/src/client/sync.rs | 4 +- components/sync15/src/client/sync_multiple.rs | 6 +- components/sync15/src/client/token.rs | 10 +- .../sync15/src/clients_engine/engine.rs | 6 +- components/sync15/src/device_type.rs | 6 +- .../sync15/src/engine/bridged_engine.rs | 4 +- components/sync15/src/engine/sync_engine.rs | 2 +- components/sync15/src/key_bundle.rs | 4 +- components/sync15/src/lib.rs | 2 +- components/sync15/src/sync15.udl | 21 -- components/sync15/src/telemetry.rs | 22 +- examples/sync-pass/src/sync-pass.rs | 8 +- 35 files changed, 94 insertions(+), 547 deletions(-) delete mode 100644 components/sync15/build.rs delete mode 100644 components/sync15/src/sync15.udl diff --git a/components/logins/Cargo.toml b/components/logins/Cargo.toml index 56f87886bf..d865689646 100644 --- a/components/logins/Cargo.toml +++ b/components/logins/Cargo.toml @@ -11,9 +11,7 @@ default = [] keydb = ["nss/keydb", "dep:async-trait", "dep:futures"] [dependencies] -# TODO: we've enabled the "standalone-sync" feature - see the description -# of this feature in sync15's Cargo.toml for what we should do instead. -sync15 = { path = "../sync15", features=["standalone-sync"] } +sync15 = { path = "../sync15" } serde = "1" serde_derive = "1" serde_json = "1" diff --git a/components/logins/src/error.rs b/components/logins/src/error.rs index a08c20225a..6198bd07a5 100644 --- a/components/logins/src/error.rs +++ b/components/logins/src/error.rs @@ -12,7 +12,6 @@ pub use error_support::{debug, error, info, trace, warn}; use error_support::{ErrorHandling, GetErrorHandling}; use jwcrypto::JwCryptoError; -use sync15::Error as Sync15Error; // Errors we return via the public interface. #[derive(Debug, thiserror::Error)] @@ -50,9 +49,6 @@ pub enum LoginsApiError { #[error("{reason}")] Interrupted { reason: String }, - #[error("SyncAuthInvalid error {reason}")] - SyncAuthInvalid { reason: String }, - #[error("Unexpected Error: {reason}")] UnexpectedLoginsApiError { reason: String }, } @@ -87,9 +83,6 @@ pub enum Error { #[error("decryption failed: {0:?}")] DecryptionFailed(String), - #[error("Error synchronizing: {0}")] - SyncAdapterError(#[from] sync15::Error), - #[error("Error parsing JSON data: {0}")] JsonError(#[from] serde_json::Error), @@ -171,24 +164,6 @@ impl GetErrorHandling for Error { Self::Interrupted(_) => ErrorHandling::convert(LoginsApiError::Interrupted { reason: self.to_string(), }), - Self::SyncAdapterError(e) => match e { - Sync15Error::TokenserverHttpError(401) | Sync15Error::BadKeyLength(..) => { - ErrorHandling::convert(LoginsApiError::SyncAuthInvalid { - reason: e.to_string(), - }) - .log_warning() - } - Sync15Error::RequestError(_) => { - ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError { - reason: e.to_string(), - }) - .log_warning() - } - _ => ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError { - reason: self.to_string(), - }) - .report_error("logins-sync"), - }, Error::SqlError(rusqlite::Error::SqliteFailure(err, _)) => match err.code { rusqlite::ErrorCode::DatabaseCorrupt => { ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError { diff --git a/components/logins/src/logins.udl b/components/logins/src/logins.udl index 5bae6d40d5..482c1fcee4 100644 --- a/components/logins/src/logins.udl +++ b/components/logins/src/logins.udl @@ -146,10 +146,6 @@ interface LoginsApiError { /// An operation was interrupted at the request of the consuming app. Interrupted(string reason); - /// Sync reported that authentication failed and the user should re-enter their FxA password. - // TODO: remove this at the same time as remove the sync() method in favour of the SyncManager. - SyncAuthInvalid(string reason); - /// something internal went wrong which doesn't have a public error value /// because the consuming app can not reasonably take any action to resolve it. /// The underlying error will have been logged and reported. diff --git a/components/logins/src/schema.rs b/components/logins/src/schema.rs index 77b028a02c..c05cde4ebc 100644 --- a/components/logins/src/schema.rs +++ b/components/logins/src/schema.rs @@ -78,15 +78,9 @@ //! This table was added (by this rust crate) in version 4, and so is not //! present in firefox-ios. //! -//! Currently it is used to store two items: -//! -//! 1. The last sync timestamp is stored under [LAST_SYNC_META_KEY], a +//! Currently it is used to store the last sync timestamp, under [LAST_SYNC_META_KEY], a //! `sync15::ServerTimestamp` stored in integer milliseconds. //! -//! 2. The persisted sync state machine information is stored under -//! [GLOBAL_STATE_META_KEY]. This is a `sync15::GlobalState` stored as -//! JSON. -//! use crate::error::*; use lazy_static::lazy_static; @@ -197,7 +191,6 @@ const CREATE_DELETED_ORIGIN_INDEX_SQL: &str = " "; pub(crate) static LAST_SYNC_META_KEY: &str = "last_sync_time"; -pub(crate) static GLOBAL_STATE_META_KEY: &str = "global_state_v2"; pub(crate) static GLOBAL_SYNCID_META_KEY: &str = "global_sync_id"; pub(crate) static COLLECTION_SYNCID_META_KEY: &str = "passwords_sync_id"; pub(crate) static CHECKPOINT_KEY: &str = "checkpoint"; diff --git a/components/logins/src/sync/engine.rs b/components/logins/src/sync/engine.rs index 0cde79e7b2..2dc721c6bc 100644 --- a/components/logins/src/sync/engine.rs +++ b/components/logins/src/sync/engine.rs @@ -297,20 +297,6 @@ impl LoginsSyncEngine { Ok(Some(ServerTimestamp(millis))) } - pub fn set_global_state(&self, state: &Option) -> Result<()> { - let to_write = match state { - Some(ref s) => s, - None => "", - }; - let db = self.store.lock_db()?; - db.put_meta(schema::GLOBAL_STATE_META_KEY, &to_write) - } - - pub fn get_global_state(&self) -> Result> { - let db = self.store.lock_db()?; - db.get_meta::(schema::GLOBAL_STATE_META_KEY) - } - fn mark_as_synchronized(&self, guids: &[&str], ts: ServerTimestamp) -> Result<()> { let db = self.store.lock_db()?; let tx = db.unchecked_transaction()?; @@ -378,7 +364,6 @@ impl LoginsSyncEngine { db.put_meta(schema::COLLECTION_SYNCID_META_KEY, &ids.coll)?; } }; - db.delete_meta(schema::GLOBAL_STATE_META_KEY)?; tx.commit()?; Ok(()) } diff --git a/components/places/Cargo.toml b/components/places/Cargo.toml index c3df5fa3e7..4839fb31f5 100644 --- a/components/places/Cargo.toml +++ b/components/places/Cargo.toml @@ -10,9 +10,7 @@ exclude = ["/android", "/ios"] default = [] [dependencies] -# TODO: we've enabled the "standalone-sync" feature - see the description -# of this feature in sync15's Cargo.toml for what we should do instead. -sync15 = { path = "../sync15", features=["standalone-sync"] } +sync15 = { path = "../sync15" } serde = "1" serde_derive = "1" serde_json = "1" diff --git a/components/places/android/src/main/java/mozilla/appservices/places/PlacesConnection.kt b/components/places/android/src/main/java/mozilla/appservices/places/PlacesConnection.kt index 0e8d3ea892..e68c414ccf 100644 --- a/components/places/android/src/main/java/mozilla/appservices/places/PlacesConnection.kt +++ b/components/places/android/src/main/java/mozilla/appservices/places/PlacesConnection.kt @@ -85,34 +85,6 @@ class PlacesApi(path: String) : PlacesManager, AutoCloseable { override fun close() { this.writeConn.apiRef.clear() } - - override fun syncHistory(syncInfo: SyncAuthInfo): SyncTelemetryPing { - val pingJSONString = this.api.historySync( - syncInfo.kid, - syncInfo.fxaAccessToken, - syncInfo.syncKey, - syncInfo.tokenserverURL, - ) - return SyncTelemetryPing.fromJSONString(pingJSONString) - } - - override fun syncBookmarks(syncInfo: SyncAuthInfo): SyncTelemetryPing { - val pingJSONString = this.api.bookmarksSync( - syncInfo.kid, - syncInfo.fxaAccessToken, - syncInfo.syncKey, - syncInfo.tokenserverURL, - ) - return SyncTelemetryPing.fromJSONString(pingJSONString) - } - - override fun resetHistorySyncMetadata() { - this.api.resetHistory() - } - - override fun resetBookmarkSyncMetadata() { - return this.api.bookmarksReset() - } } @Suppress("TooGenericExceptionCaught") @@ -530,50 +502,6 @@ interface PlacesManager { * This should always return the same object. */ fun getWriter(): WritableHistoryConnection - - /** - * Syncs the places history store, returning a telemetry ping. - * - * Note that this function blocks until the sync is complete, which may - * take some time due to the network etc. Because only 1 thread can be - * using a PlacesAPI at a time, it is recommended, but not enforced, that - * you have all connections you intend using open before calling this. - */ - fun syncHistory(syncInfo: SyncAuthInfo): SyncTelemetryPing - - /** - * Syncs the places bookmarks store, returning a telemetry ping. - * - * Note that this function blocks until the sync is complete, which may - * take some time due to the network etc. Because only 1 thread can be - * using a PlacesAPI at a time, it is recommended, but not enforced, that - * you have all connections you intend using open before calling this. - */ - fun syncBookmarks(syncInfo: SyncAuthInfo): SyncTelemetryPing - - /** - * Resets all sync metadata for history, including change flags, - * sync statuses, and last sync time. The next sync after reset - * will behave the same way as a first sync when connecting a new - * device. - * - * This method only needs to be called when the user disconnects - * from Sync. There are other times when Places resets sync metadata, - * but those are handled internally in the Rust code. - */ - fun resetHistorySyncMetadata() - - /** - * Resets all sync metadata for bookmarks, including change flags, - * sync statuses, and last sync time. The next sync after reset - * will behave the same way as a first sync when connecting a new - * device. - * - * This method only needs to be called when the user disconnects - * from Sync. There are other times when Places resets sync metadata, - * but those are handled internally in the Rust code. - */ - fun resetBookmarkSyncMetadata() } interface InterruptibleConnection : AutoCloseable { diff --git a/components/places/src/api/places_api.rs b/components/places/src/api/places_api.rs index c471ec6f06..54ce0d48e8 100644 --- a/components/places/src/api/places_api.rs +++ b/components/places/src/api/places_api.rs @@ -6,32 +6,19 @@ use crate::bookmark_sync::BookmarksSyncEngine; use crate::db::db::{PlacesDb, SharedPlacesDb}; use crate::error::*; use crate::history_sync::HistorySyncEngine; -use crate::storage::{ - self, bookmarks::bookmark_sync, delete_meta, get_meta, history::history_sync, put_meta, -}; use crate::util::normalize_path; use error_support::handle_error; use interrupt_support::register_interrupt; use lazy_static::lazy_static; use parking_lot::Mutex; use rusqlite::OpenFlags; -use std::cell::Cell; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, Weak, }; -use sync15::client::{sync_multiple, MemoryCachedState, Sync15StorageClientInit, SyncResult}; -use sync15::engine::{EngineSyncAssociation, SyncEngine, SyncEngineId}; -use sync15::{telemetry, KeyBundle}; - -// Not clear if this should be here, but this is the "global sync state" -// which is persisted to disk and reused for all engines. -// Note that this is only ever round-tripped, and never changed by, or impacted -// by a store or collection, so it's safe to storage globally rather than -// per collection. -pub const GLOBAL_STATE_META_KEY: &str = "global_sync_state_v2"; +use sync15::engine::{SyncEngine, SyncEngineId}; // Our "sync manager" will use whatever is stashed here. lazy_static::lazy_static! { @@ -121,11 +108,6 @@ lazy_static! { static ID_COUNTER: AtomicUsize = AtomicUsize::new(0); -pub struct SyncState { - pub mem_cached_state: Cell, - pub disk_cached_state: Cell>, -} - /// For uniffi we need to expose our `Arc` returning constructor as a global function :( /// https://github.com/mozilla/uniffi-rs/pull/1063 would fix this, but got some pushback /// meaning we are forced into this unfortunate workaround. @@ -140,7 +122,6 @@ pub fn places_api_new(db_name: impl AsRef) -> ApiResult> { pub struct PlacesApi { db_name: PathBuf, write_connection: Mutex>, - sync_state: Mutex>, coop_tx_lock: Arc>, // Used for get_sync_connection() // - The inner mutex synchronizes sync operation (for example one of the [SyncEngine] methods). @@ -188,7 +169,6 @@ impl PlacesApi { let new = PlacesApi { db_name: db_name.clone(), write_connection: Mutex::new(Some(connection)), - sync_state: Mutex::new(None), sync_connection: Mutex::new(Weak::new()), id, coop_tx_lock, @@ -275,17 +255,6 @@ impl PlacesApi { Ok(()) } - fn get_disk_persisted_state(&self, conn: &PlacesDb) -> Result> { - get_meta::(conn, GLOBAL_STATE_META_KEY) - } - - fn set_disk_persisted_state(&self, conn: &PlacesDb, state: &Option) -> Result<()> { - match state { - Some(ref s) => put_meta(conn, GLOBAL_STATE_META_KEY, s), - None => delete_meta(conn, GLOBAL_STATE_META_KEY), - } - } - // This allows the embedding app to say "make this instance available to // the sync manager". The implementation is more like "offer to sync mgr" // (thereby avoiding us needing to link with the sync manager) but @@ -294,177 +263,6 @@ impl PlacesApi { pub fn register_with_sync_manager(self: Arc) { *PLACES_API_FOR_SYNC_MANAGER.lock() = Arc::downgrade(&self); } - - // NOTE: These should be deprecated as soon as possible - that will be once - // all consumers have been updated to use the .sync() method below, and/or - // we have implemented the sync manager and migrated consumers to that. - pub fn sync_history( - &self, - client_init: &Sync15StorageClientInit, - key_bundle: &KeyBundle, - ) -> Result { - self.do_sync_one( - "history", - move |conn, mem_cached_state, disk_cached_state| { - let engine = HistorySyncEngine::new(conn)?; - Ok(sync_multiple( - &[&engine], - disk_cached_state, - mem_cached_state, - client_init, - key_bundle, - &interrupt_support::ShutdownInterruptee, - None, - )) - }, - ) - } - - pub fn sync_bookmarks( - &self, - client_init: &Sync15StorageClientInit, - key_bundle: &KeyBundle, - ) -> Result { - self.do_sync_one( - "bookmarks", - move |conn, mem_cached_state, disk_cached_state| { - let engine = BookmarksSyncEngine::new(conn)?; - Ok(sync_multiple( - &[&engine], - disk_cached_state, - mem_cached_state, - client_init, - key_bundle, - &interrupt_support::ShutdownInterruptee, - None, - )) - }, - ) - } - - pub fn do_sync_one( - &self, - name: &'static str, - syncer: F, - ) -> Result - where - F: FnOnce( - Arc, - &mut MemoryCachedState, - &mut Option, - ) -> Result, - { - let mut guard = self.sync_state.lock(); - let conn = self.get_sync_connection()?; - if guard.is_none() { - *guard = Some(SyncState { - mem_cached_state: Cell::default(), - disk_cached_state: Cell::new(self.get_disk_persisted_state(&conn.lock())?), - }); - } - - let sync_state = guard.as_ref().unwrap(); - - let mut mem_cached_state = sync_state.mem_cached_state.take(); - let mut disk_cached_state = sync_state.disk_cached_state.take(); - let mut result = syncer(conn.clone(), &mut mem_cached_state, &mut disk_cached_state)?; - // even on failure we set the persisted state - sync itself takes care - // to ensure this has been None'd out if necessary. - self.set_disk_persisted_state(&conn.lock(), &disk_cached_state)?; - sync_state.mem_cached_state.replace(mem_cached_state); - sync_state.disk_cached_state.replace(disk_cached_state); - - // for b/w compat reasons, we do some dances with the result. - if let Err(e) = result.result { - return Err(e.into()); - } - match result.engine_results.remove(name) { - None | Some(Ok(())) => Ok(result.telemetry), - Some(Err(e)) => Err(e.into()), - } - } - - // This is the new sync API until the sync manager lands. It's currently - // not wired up via the FFI - it's possible we'll do declined engines too - // before we do. - // Note we've made a policy decision about the return value - even though - // it is Result, we will only return an Err() if there's a - // fatal error that prevents us starting a sync, such as failure to open - // the DB. Any errors that happen *after* sync must not escape - ie, once - // we have a SyncResult, we must return it. - pub fn sync( - &self, - client_init: &Sync15StorageClientInit, - key_bundle: &KeyBundle, - ) -> Result { - let mut guard = self.sync_state.lock(); - let conn = self.get_sync_connection()?; - if guard.is_none() { - *guard = Some(SyncState { - mem_cached_state: Cell::default(), - disk_cached_state: Cell::new(self.get_disk_persisted_state(&conn.lock())?), - }); - } - - let sync_state = guard.as_ref().unwrap(); - - let bm_engine = BookmarksSyncEngine::new(conn.clone())?; - let history_engine = HistorySyncEngine::new(conn.clone())?; - let mut mem_cached_state = sync_state.mem_cached_state.take(); - let mut disk_cached_state = sync_state.disk_cached_state.take(); - - // NOTE: After here we must never return Err()! - let result = sync_multiple( - &[&history_engine, &bm_engine], - &mut disk_cached_state, - &mut mem_cached_state, - client_init, - key_bundle, - &interrupt_support::ShutdownInterruptee, - None, - ); - // even on failure we set the persisted state - sync itself takes care - // to ensure this has been None'd out if necessary. - if let Err(e) = self.set_disk_persisted_state(&conn.lock(), &disk_cached_state) { - error_support::report_error!( - "places-sync-persist-failure", - "Failed to persist the sync state: {:?}", - e - ); - } - sync_state.mem_cached_state.replace(mem_cached_state); - sync_state.disk_cached_state.replace(disk_cached_state); - - Ok(result) - } - - pub fn wipe_bookmarks(&self) -> Result<()> { - // Take the lock to prevent syncing while we're doing this. - let _guard = self.sync_state.lock(); - let conn = self.get_sync_connection()?; - - storage::bookmarks::delete_everything(&conn.lock())?; - Ok(()) - } - - pub fn reset_bookmarks(&self) -> Result<()> { - // Take the lock to prevent syncing while we're doing this. - let _guard = self.sync_state.lock(); - let conn = self.get_sync_connection()?; - - bookmark_sync::reset(&conn.lock(), &EngineSyncAssociation::Disconnected)?; - Ok(()) - } - - #[handle_error(crate::Error)] - pub fn reset_history(&self) -> ApiResult<()> { - // Take the lock to prevent syncing while we're doing this. - let _guard = self.sync_state.lock(); - let conn = self.get_sync_connection()?; - - history_sync::reset(&conn.lock(), &EngineSyncAssociation::Disconnected)?; - Ok(()) - } } #[cfg(test)] diff --git a/components/places/src/bookmark_sync/incoming.rs b/components/places/src/bookmark_sync/incoming.rs index a8c1a412e3..ffe20bee94 100644 --- a/components/places/src/bookmark_sync/incoming.rs +++ b/components/places/src/bookmark_sync/incoming.rs @@ -493,7 +493,7 @@ fn fixup_bookmark_json(json: &mut JsonValue) -> SyncedBookmarkValidity { let mut validity = SyncedBookmarkValidity::Valid; // the json value should always be on object, if not don't try to do any fixups. The result will // be that into_content_with_fixup() returns an IncomingContent with IncomingKind::Malformed. - if let JsonValue::Object(ref mut obj) = json { + if let JsonValue::Object(obj) = json { obj.entry("parentid") .and_modify(|v| fixup_optional_str(v, &mut validity)); obj.entry("title") @@ -567,7 +567,7 @@ fn fixup_optional_keyword(val: &mut JsonValue, validity: &mut SyncedBookmarkVali fn fixup_optional_tags(val: &mut JsonValue, validity: &mut SyncedBookmarkValidity) { match val { - JsonValue::Array(ref tags) => { + JsonValue::Array(tags) => { let mut valid_tags = HashSet::with_capacity(tags.len()); for v in tags { if let JsonValue::String(tag) = v { diff --git a/components/places/src/error.rs b/components/places/src/error.rs index 4dfd0a8767..3c00949aed 100644 --- a/components/places/src/error.rs +++ b/components/places/src/error.rs @@ -58,9 +58,6 @@ pub enum Error { #[error("The store is corrupt: {0}")] Corruption(#[from] Corruption), - #[error("Error synchronizing: {0}")] - SyncAdapterError(#[from] sync15::Error), - #[error("Error merging: {0}")] MergeError(#[from] dogear::Error), @@ -262,27 +259,6 @@ impl GetErrorHandling for Error { }) .report_error("places-bookmarks-corruption") } - Error::SyncAdapterError(e) => { - match e { - sync15::Error::StoreError(store_error) => { - // If it's a type-erased version of one of our errors, try - // and resolve it. - if let Some(places_err) = store_error.downcast_ref::() { - info!("Recursing to resolve places error"); - places_err.get_error_handling() - } else { - ErrorHandling::convert(PlacesApiError::UnexpectedPlacesException { - reason: self.to_string(), - }) - .report_error("places-unexpected-sync-error") - } - } - _ => ErrorHandling::convert(PlacesApiError::UnexpectedPlacesException { - reason: self.to_string(), - }) - .report_error("places-unexpected-sync-error"), - } - } Error::InvalidMetadataObservation(InvalidMetadataObservation::ViewTimeTooLong) => { ErrorHandling::convert(PlacesApiError::UnexpectedPlacesException { reason: self.to_string(), diff --git a/components/places/src/ffi.rs b/components/places/src/ffi.rs index 39386398fa..f5e35f645b 100644 --- a/components/places/src/ffi.rs +++ b/components/places/src/ffi.rs @@ -30,7 +30,6 @@ use interrupt_support::register_interrupt; pub use interrupt_support::SqlInterruptHandle; use parking_lot::Mutex; use std::sync::{Arc, Weak}; -use sync15::client::Sync15StorageClientInit; pub use sync_guid::Guid; pub use types::Timestamp as PlacesTimestamp; pub use url::Url; @@ -103,55 +102,6 @@ impl PlacesApi { register_interrupt(Arc::::downgrade(&connection)); Ok(connection) } - - // NOTE: These methods are unused on Android but will remain needed for - // iOS until we can move them to the sync manager and replace their existing - // sync engines with ours - #[handle_error(crate::Error)] - pub fn history_sync( - &self, - key_id: String, - access_token: String, - sync_key: String, - tokenserver_url: Url, - ) -> ApiResult { - let root_sync_key = sync15::KeyBundle::from_ksync_base64(sync_key.as_str())?; - let ping = self.sync_history( - &Sync15StorageClientInit { - key_id, - access_token, - tokenserver_url, - }, - &root_sync_key, - )?; - Ok(serde_json::to_string(&ping).unwrap()) - } - - #[handle_error(crate::Error)] - pub fn bookmarks_sync( - &self, - key_id: String, - access_token: String, - sync_key: String, - tokenserver_url: Url, - ) -> ApiResult { - let root_sync_key = sync15::KeyBundle::from_ksync_base64(sync_key.as_str())?; - let ping = self.sync_bookmarks( - &Sync15StorageClientInit { - key_id, - access_token, - tokenserver_url, - }, - &root_sync_key, - )?; - Ok(serde_json::to_string(&ping).unwrap()) - } - - #[handle_error(crate::Error)] - pub fn bookmarks_reset(&self) -> ApiResult<()> { - self.reset_bookmarks()?; - Ok(()) - } } pub struct PlacesConnection { diff --git a/components/places/src/places.udl b/components/places/src/places.udl index b626ef7f4e..dff00c40ac 100644 --- a/components/places/src/places.udl +++ b/components/places/src/places.udl @@ -33,18 +33,6 @@ interface PlacesApi { [Self=ByArc] void register_with_sync_manager(); - - [Throws=PlacesApiError] - void reset_history(); - - [Throws=PlacesApiError] - string history_sync(string key_id, string access_token, string sync_key, Url tokenserver_url); - - [Throws=PlacesApiError] - string bookmarks_sync(string key_id, string access_token, string sync_key, Url tokenserver_url); - - [Throws=PlacesApiError] - void bookmarks_reset(); }; interface PlacesConnection { diff --git a/components/sync15/Cargo.toml b/components/sync15/Cargo.toml index 9e53ad75d2..9ae60652b5 100644 --- a/components/sync15/Cargo.toml +++ b/components/sync15/Cargo.toml @@ -1,8 +1,7 @@ [package] name = "sync15" -edition = "2021" +edition = "2024" version = "0.1.0" -authors = ["Sync Team "] license = "MPL-2.0" exclude = ["/android", "/ios"] @@ -16,34 +15,18 @@ random-guid = ["sync-guid/random"] # Some consumers of this just need our encrypted payloads and no other sync functionality. crypto = ["rc_crypto", "base16", "base64"] -# Some crates need to implement a "sync engine", but aren't a "sync client" (ie, their -# engine is used by a "sync client".) Engines don't interact directly with the storage servers, -# nor do they do their own crypto. +# Some libraries need to implement a "sync engine", but aren't a "sync client" (ie, their +# engine is used by an external "sync client", like on desktop). +# Engines don't interact directly with the storage servers, nor do they do their own crypto. # See the rustdocs in `crate::engine` for more information about engines. sync-engine = ["random-guid"] -# Some crates are a "sync client" and do full management/initialization of server storage, -# keys, etc and sync one or more engines. This crate has an engine to manage the "clients" -# collection, so needs the sync-engine feature. +# Some libraries are a "sync client" and do full management/initialization of server storage, +# keys, etc and sync one or more engines. This feature will enable this crate to have a `clients` +# engine to manage state in the `clients` collection - thus, it requires the `sync-engine` feature. # See the rustdocs in `crate::client` for more information about clients. sync-client = ["sync-engine", "crypto", "viaduct", "url"] -# Some crates just do their own engine but need to pretend they are a client, -# eg, iOS pre-sync-manager. -# Consider places: -# * It always is going to need to supply a "sync-engine". -# * When used in iOS, due to the lack of sync_manager support, it also needs to -# supply a kind of "sync-client". It is *not* necessary to supply this for Android. -# In a perfect world: -# * places would also have a feature called, say, "sync-client" -# * The code needed for iOS would be behind the "sync-client" feature. -# * The ios megazord would enable the "sync-client" feature, but the android megazord would not. -# -# However, that's not yet the case. This "stand-alone" sync feature is used by crates -# such as places, and is really a marker to help identify the crates which should be -# upgraded to make the sync-client part truly optional. -standalone-sync = ["sync-client"] - [dependencies] anyhow = "1.0" base16 = { version = "0.2", optional = true } @@ -66,6 +49,3 @@ viaduct = { path = "../viaduct", optional = true } [dev-dependencies] error-support = { path = "../support/error", features = ["testing"] } nss = { path = "../support/rc_crypto/nss" } - -[build-dependencies] -uniffi = { version = "0.29.0", features=["build"]} diff --git a/components/sync15/build.rs b/components/sync15/build.rs deleted file mode 100644 index a4c1bb8d4e..0000000000 --- a/components/sync15/build.rs +++ /dev/null @@ -1,7 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -fn main() { - uniffi::generate_scaffolding("./src/sync15.udl").unwrap(); -} diff --git a/components/sync15/src/bso/content.rs b/components/sync15/src/bso/content.rs index 4f3e09385f..f40d773d1e 100644 --- a/components/sync15/src/bso/content.rs +++ b/components/sync15/src/bso/content.rs @@ -10,8 +10,8 @@ //! * Turn arbitrary objects with an `id` field into an OutgoingBso. use super::{IncomingBso, IncomingContent, IncomingKind, OutgoingBso, OutgoingEnvelope}; -use crate::error::{trace, warn}; use crate::Guid; +use crate::error::{trace, warn}; use error_support::report_error; use serde::Serialize; @@ -143,8 +143,7 @@ where if content_id != id { trace!( "malformed incoming record: envelope id: {} payload id: {}", - content_id, - id + content_id, id ); report_error!( "incoming-invalid-mismatched-ids", diff --git a/components/sync15/src/bso/crypto.rs b/components/sync15/src/bso/crypto.rs index d572c4692b..4e58843aec 100644 --- a/components/sync15/src/bso/crypto.rs +++ b/components/sync15/src/bso/crypto.rs @@ -6,10 +6,10 @@ //! This module decrypts them into IncomingBso's suitable for use by the //! engines. use super::{IncomingBso, IncomingEnvelope, OutgoingBso, OutgoingEnvelope}; +use crate::EncryptedPayload; use crate::error; use crate::key_bundle::KeyBundle; -use crate::EncryptedPayload; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; // The BSO implementation we use for encrypted payloads. // Note that this is almost identical to the IncomingBso implementations, except diff --git a/components/sync15/src/client/coll_state.rs b/components/sync15/src/client/coll_state.rs index d4fba5bd65..cf3c98f5be 100644 --- a/components/sync15/src/client/coll_state.rs +++ b/components/sync15/src/client/coll_state.rs @@ -4,11 +4,11 @@ use super::request::InfoConfiguration; use super::{CollectionKeys, GlobalState}; +use crate::KeyBundle; +use crate::ServerTimestamp; use crate::engine::{CollSyncIds, EngineSyncAssociation, SyncEngine}; use crate::error; use crate::error::{info, trace, warn}; -use crate::KeyBundle; -use crate::ServerTimestamp; /// Holds state for a collection necessary to perform a sync of it. Lives for the lifetime /// of a single sync. @@ -166,13 +166,13 @@ impl<'state> LocalCollStateMachine<'state> { #[cfg(test)] mod tests { - use super::super::request::{InfoCollections, InfoConfiguration}; use super::super::CollectionKeys; + use super::super::request::{InfoCollections, InfoConfiguration}; use super::*; use crate::bso::{IncomingBso, OutgoingBso}; use crate::engine::CollectionRequest; use crate::record_types::{MetaGlobalEngine, MetaGlobalRecord}; - use crate::{telemetry, CollectionName}; + use crate::{CollectionName, telemetry}; use anyhow::Result; use nss::ensure_initialized; use std::cell::{Cell, RefCell}; diff --git a/components/sync15/src/client/coll_update.rs b/components/sync15/src/client/coll_update.rs index 87430b7727..2164a6d669 100644 --- a/components/sync15/src/client/coll_update.rs +++ b/components/sync15/src/client/coll_update.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::{ - request::{NormalResponseHandler, UploadInfo}, CollState, Sync15ClientResponse, Sync15StorageClient, + request::{NormalResponseHandler, UploadInfo}, }; use crate::bso::{IncomingBso, OutgoingBso, OutgoingEncryptedBso}; use crate::engine::CollectionRequest; diff --git a/components/sync15/src/client/mod.rs b/components/sync15/src/client/mod.rs index c49486bfe6..e13a6334b2 100644 --- a/components/sync15/src/client/mod.rs +++ b/components/sync15/src/client/mod.rs @@ -26,7 +26,7 @@ mod token; mod util; pub(crate) use coll_state::{CollState, LocalCollStateMachine}; -pub(crate) use coll_update::{fetch_incoming, CollectionUpdate}; +pub(crate) use coll_update::{CollectionUpdate, fetch_incoming}; pub(crate) use collection_keys::CollectionKeys; pub(crate) use request::InfoConfiguration; pub(crate) use state::GlobalState; @@ -35,5 +35,5 @@ pub use storage_client::{ SetupStorageClient, Sync15ClientResponse, Sync15StorageClient, Sync15StorageClientInit, }; pub use sync_multiple::{ - sync_multiple, sync_multiple_with_command_processor, MemoryCachedState, SyncRequestInfo, + MemoryCachedState, SyncRequestInfo, sync_multiple, sync_multiple_with_command_processor, }; diff --git a/components/sync15/src/client/request.rs b/components/sync15/src/client/request.rs index 3c2a21c8ed..e21629fe77 100644 --- a/components/sync15/src/client/request.rs +++ b/components/sync15/src/client/request.rs @@ -3,9 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::storage_client::Sync15ClientResponse; -use crate::bso::OutgoingEncryptedBso; -use crate::error::{self, debug, info, warn, Error as ErrorKind, Result}; use crate::ServerTimestamp; +use crate::bso::OutgoingEncryptedBso; +use crate::error::{self, Error as ErrorKind, Result, debug, info, warn}; use serde_derive::*; use std::collections::HashMap; use std::default::Default; @@ -348,7 +348,7 @@ where // First commit in possible batch BatchState::NoBatch => Some("true".into()), // In a batch and we have a batch id. - BatchState::InBatch(ref s) => Some(s.clone()), + BatchState::InBatch(s) => Some(s.clone()), }; info!( @@ -427,7 +427,7 @@ where warn!("Server changed its mind about supporting batching mid-batch..."); } - BatchState::InBatch(ref cur_id) => { + BatchState::InBatch(cur_id) => { if cur_id != &batch_id { return Err(ErrorKind::ServerBatchProblem( "Invalid server response: 202 without a batch ID", @@ -486,8 +486,8 @@ impl PostQueue { #[cfg(test)] mod test { use super::*; - use crate::bso::{IncomingEncryptedBso, OutgoingEncryptedBso, OutgoingEnvelope}; use crate::EncryptedPayload; + use crate::bso::{IncomingEncryptedBso, OutgoingEncryptedBso, OutgoingEnvelope}; use lazy_static::lazy_static; use std::cell::RefCell; use std::collections::VecDeque; diff --git a/components/sync15/src/client/state.rs b/components/sync15/src/client/state.rs index 11932a175b..564701858e 100644 --- a/components/sync15/src/client/state.rs +++ b/components/sync15/src/client/state.rs @@ -4,13 +4,13 @@ use std::collections::{HashMap, HashSet}; +use super::CollectionKeys; use super::request::{InfoCollections, InfoConfiguration}; use super::storage_client::{SetupStorageClient, Sync15ClientResponse}; -use super::CollectionKeys; +use crate::EncryptedPayload; use crate::bso::OutgoingEncryptedBso; -use crate::error::{self, debug, info, trace, warn, Error as ErrorKind, ErrorResponse}; +use crate::error::{self, Error as ErrorKind, ErrorResponse, debug, info, trace, warn}; use crate::record_types::{MetaGlobalEngine, MetaGlobalRecord}; -use crate::EncryptedPayload; use crate::{Guid, KeyBundle, ServerTimestamp}; use interrupt_support::Interruptee; use serde_derive::*; @@ -144,7 +144,7 @@ fn compute_engine_states(input: EngineStateInput) -> EngineStateOutput { impl PersistedGlobalState { fn set_declined(&mut self, new_declined: Vec) { match self { - Self::V2 { ref mut declined } => *declined = Some(new_declined), + Self::V2 { declined } => *declined = Some(new_declined), } } pub(crate) fn get_declined(&self) -> &[String] { @@ -353,7 +353,9 @@ impl<'a> SetupStateMachine<'a> { if global.storage_version < STORAGE_VERSION { Ok(FreshStartRequired { config }) } else { - info!("Have info/collections and meta/global. Computing new engine states"); + info!( + "Have info/collections and meta/global. Computing new engine states" + ); let initial_global_declined: HashSet = global.declined.iter().cloned().collect(); let result = compute_engine_states(EngineStateInput { @@ -372,8 +374,7 @@ impl<'a> SetupStateMachine<'a> { global.declined = result.declined.iter().cloned().collect(); info!( "Uploading new declined {:?} to meta/global with timestamp {:?}", - global.declined, - global_timestamp, + global.declined, global_timestamp, ); true } else { @@ -666,10 +667,12 @@ mod tests { global: &MetaGlobalRecord, ) -> error::Result { // Ensure that the meta/global record we uploaded is "fixed up" - assert!(DEFAULT_ENGINES - .iter() - .filter(|e| e.0 != "logins") - .all(|&(k, _v)| global.engines.contains_key(k))); + assert!( + DEFAULT_ENGINES + .iter() + .filter(|e| e.0 != "logins") + .all(|&(k, _v)| global.engines.contains_key(k)) + ); assert!(!global.engines.contains_key("logins")); assert_eq!(global.declined, vec!["logins".to_string()]); // return a different timestamp. diff --git a/components/sync15/src/client/status.rs b/components/sync15/src/client/status.rs index 407efeec12..a34bed5d87 100644 --- a/components/sync15/src/client/status.rs +++ b/components/sync15/src/client/status.rs @@ -44,7 +44,7 @@ impl ServiceStatus { } // BackoffError is also from the tokenserver. Error::BackoffError(_) => ServiceStatus::ServiceError, - Error::StorageHttpError(ref e) => match e { + Error::StorageHttpError(e) => match e { ErrorResponse::Unauthorized { .. } => ServiceStatus::AuthenticationError, _ => ServiceStatus::ServiceError, }, @@ -84,10 +84,10 @@ pub struct SyncResult { // If `r` has a BackoffError, then returns the later backoff value. fn advance_backoff(cur_best: SystemTime, r: &Result<(), Error>) -> SystemTime { - if let Err(e) = r { - if let Some(time) = e.get_backoff() { - return std::cmp::max(time, cur_best); - } + if let Err(e) = r + && let Some(time) = e.get_backoff() + { + return std::cmp::max(time, cur_best); } cur_best } diff --git a/components/sync15/src/client/storage_client.rs b/components/sync15/src/client/storage_client.rs index ca38c18876..4066e31433 100644 --- a/components/sync15/src/client/storage_client.rs +++ b/components/sync15/src/client/storage_client.rs @@ -8,7 +8,7 @@ use super::request::{ use super::token; use crate::bso::{IncomingBso, IncomingEncryptedBso, OutgoingBso, OutgoingEncryptedBso}; use crate::engine::{CollectionPost, CollectionRequest}; -use crate::error::{self, debug, info, trace, warn, Error, ErrorResponse}; +use crate::error::{self, Error, ErrorResponse, debug, info, trace, warn}; use crate::record_types::MetaGlobalRecord; use crate::{CollectionName, Guid, ServerTimestamp}; use serde_json::Value; @@ -16,8 +16,8 @@ use std::str::FromStr; use std::sync::atomic::{AtomicU32, Ordering}; use url::Url; use viaduct::{ - header_names::{self, AUTHORIZATION}, Method, Request, Response, + header_names::{self, AUTHORIZATION}, }; /// A response from a GET request on a Sync15StorageClient, encapsulating all @@ -565,8 +565,10 @@ mod test { .newer_than(ServerTimestamp(1_234_560)), ) .unwrap(); - assert_eq!(complex.as_str(), - "https://example.com/sync/storage/specific?full=1&older=9876.54&newer=1234.56&sort=oldest&limit=10"); + assert_eq!( + complex.as_str(), + "https://example.com/sync/storage/specific?full=1&older=9876.54&newer=1234.56&sort=oldest&limit=10" + ); } #[cfg(feature = "sync-client")] diff --git a/components/sync15/src/client/sync.rs b/components/sync15/src/client/sync.rs index 9f07fe43c4..f680afaa27 100644 --- a/components/sync15/src/client/sync.rs +++ b/components/sync15/src/client/sync.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::{CollectionUpdate, GlobalState, LocalCollStateMachine, Sync15StorageClient}; +use crate::KeyBundle; use crate::clients_engine; use crate::engine::SyncEngine; -use crate::error::{info, warn, Error}; +use crate::error::{Error, info, warn}; use crate::telemetry; -use crate::KeyBundle; use interrupt_support::Interruptee; #[allow(clippy::too_many_arguments)] diff --git a/components/sync15/src/client/sync_multiple.rs b/components/sync15/src/client/sync_multiple.rs index dbc4ad4351..e24d0d4410 100644 --- a/components/sync15/src/client/sync_multiple.rs +++ b/components/sync15/src/client/sync_multiple.rs @@ -8,11 +8,11 @@ use super::state::{EngineChangesNeeded, GlobalState, PersistedGlobalState, SetupStateMachine}; use super::status::{ServiceStatus, SyncResult}; use super::storage_client::{BackoffListener, Sync15StorageClient, Sync15StorageClientInit}; -use crate::clients_engine::{self, CommandProcessor, CLIENTS_TTL_REFRESH}; +use crate::KeyBundle; +use crate::clients_engine::{self, CLIENTS_TTL_REFRESH, CommandProcessor}; use crate::engine::{EngineSyncAssociation, SyncEngine}; -use crate::error::{debug, info, trace, warn, Error}; +use crate::error::{Error, debug, info, trace, warn}; use crate::telemetry; -use crate::KeyBundle; use interrupt_support::Interruptee; use std::collections::HashMap; use std::result; diff --git a/components/sync15/src/client/token.rs b/components/sync15/src/client/token.rs index fed19ae271..86ae17084e 100644 --- a/components/sync15/src/client/token.rs +++ b/components/sync15/src/client/token.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::error::{self, debug, trace, warn, Error as ErrorKind, Result}; use crate::ServerTimestamp; +use crate::error::{self, Error as ErrorKind, Result, debug, trace, warn}; use rc_crypto::hawk; use serde_derive::*; use std::borrow::{Borrow, Cow}; @@ -11,7 +11,7 @@ use std::cell::RefCell; use std::fmt; use std::time::{Duration, SystemTime}; use url::Url; -use viaduct::{header_names, Request}; +use viaduct::{Request, header_names}; const RETRY_AFTER_DEFAULT_MS: u64 = 10000; @@ -328,7 +328,7 @@ impl TokenProviderImpl { Some(self.fetch_token(Some(existing_context.token.api_endpoint.as_str()))) } } - TokenState::Backoff(ref until, ref existing_endpoint) => { + TokenState::Backoff(until, existing_endpoint) => { if let Ok(remaining) = until.duration_since(self.fetcher.now()) { debug!("enforcing existing backoff - {:?} remains", remaining); None @@ -362,7 +362,7 @@ impl TokenProviderImpl { // it should be impossible to get here. panic!("Can't be in NoToken state after advancing"); } - TokenState::Token(ref token_context) => { + TokenState::Token(token_context) => { // make the call. func(token_context) } @@ -374,7 +374,7 @@ impl TokenProviderImpl { // this is unrecoverable. Err(ErrorKind::StorageResetError) } - TokenState::Backoff(ref remaining, _) => Err(ErrorKind::BackoffError(*remaining)), + TokenState::Backoff(remaining, _) => Err(ErrorKind::BackoffError(*remaining)), } } diff --git a/components/sync15/src/clients_engine/engine.rs b/components/sync15/src/clients_engine/engine.rs index 436afa5b9d..dd43b8c28f 100644 --- a/components/sync15/src/clients_engine/engine.rs +++ b/components/sync15/src/clients_engine/engine.rs @@ -11,14 +11,14 @@ use crate::client::{ }; use crate::client_types::{ClientData, RemoteClient}; use crate::engine::CollectionRequest; -use crate::error::{debug, info, warn, Result}; +use crate::error::{Result, debug, info, warn}; use crate::{Guid, KeyBundle}; use interrupt_support::Interruptee; use super::{ + CLIENTS_TTL, Command, CommandProcessor, CommandStatus, record::{ClientRecord, CommandRecord}, ser::shrink_to_fit, - Command, CommandProcessor, CommandStatus, CLIENTS_TTL, }; const COLLECTION_NAME: &str = "clients"; @@ -362,7 +362,7 @@ mod tests { use crate::bso::IncomingBso; use anyhow::Result; use interrupt_support::NeverInterrupts; - use serde_json::{json, Value}; + use serde_json::{Value, json}; use std::iter::zip; struct TestProcessor { diff --git a/components/sync15/src/device_type.rs b/components/sync15/src/device_type.rs index 8b4ed9593b..abe4068bc4 100644 --- a/components/sync15/src/device_type.rs +++ b/components/sync15/src/device_type.rs @@ -14,8 +14,10 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// /// Firefox Accounts and the broader Sync universe separates devices into broad categories for /// various purposes, such as distinguishing a desktop PC from a mobile phone. +/// Upon signin, the application should inspect the device it is running on and select an appropriate +/// [`DeviceType`] to include in its device registration record. /// -/// A special variant in this enum, `DeviceType::Unknown` is used to capture +/// A special variant in this enum, [`DeviceType::Unknown`] is used to capture /// the string values we don't recognise. It also has a custom serde serializer and deserializer /// which implements the following semantics: /// * deserializing a `DeviceType` which uses a string value we don't recognise or null will return @@ -32,7 +34,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// upload records with *this* device's type, not the type of other devices, and it's reasonable /// to assume that this module knows about all valid device types for the device type it is /// deployed on. -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, uniffi::Enum)] pub enum DeviceType { Desktop, Mobile, diff --git a/components/sync15/src/engine/bridged_engine.rs b/components/sync15/src/engine/bridged_engine.rs index e1781eb2ec..6cb9c2ffa2 100644 --- a/components/sync15/src/engine/bridged_engine.rs +++ b/components/sync15/src/engine/bridged_engine.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::error::debug; -use crate::{telemetry, ServerTimestamp}; +use crate::{ServerTimestamp, telemetry}; use anyhow::Result; -use crate::bso::{IncomingBso, OutgoingBso}; use crate::Guid; +use crate::bso::{IncomingBso, OutgoingBso}; use super::{CollSyncIds, EngineSyncAssociation, SyncEngine}; diff --git a/components/sync15/src/engine/sync_engine.rs b/components/sync15/src/engine/sync_engine.rs index bc57e354d1..83b50b866e 100644 --- a/components/sync15/src/engine/sync_engine.rs +++ b/components/sync15/src/engine/sync_engine.rs @@ -5,7 +5,7 @@ use super::CollectionRequest; use crate::bso::{IncomingBso, OutgoingBso}; use crate::client_types::ClientData; -use crate::{telemetry, CollectionName, Guid, ServerTimestamp}; +use crate::{CollectionName, Guid, ServerTimestamp, telemetry}; use anyhow::Result; use std::fmt; diff --git a/components/sync15/src/key_bundle.rs b/components/sync15/src/key_bundle.rs index 2032c2e8f5..c8d6875270 100644 --- a/components/sync15/src/key_bundle.rs +++ b/components/sync15/src/key_bundle.rs @@ -2,10 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::error::{warn, Error, Result}; +use crate::error::{Error, Result, warn}; use base64::{ - engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}, Engine, + engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}, }; use rc_crypto::{ aead::{self, OpeningKey, SealingKey}, diff --git a/components/sync15/src/lib.rs b/components/sync15/src/lib.rs index 1c9c82b991..a57f9f973b 100644 --- a/components/sync15/src/lib.rs +++ b/components/sync15/src/lib.rs @@ -48,4 +48,4 @@ fn skip_if_default(v: &T) -> bool { *v == T::default() } -uniffi::include_scaffolding!("sync15"); +uniffi::setup_scaffolding!("sync15"); diff --git a/components/sync15/src/sync15.udl b/components/sync15/src/sync15.udl deleted file mode 100644 index 6837cbea3f..0000000000 --- a/components/sync15/src/sync15.udl +++ /dev/null @@ -1,21 +0,0 @@ -// # sync15 types - -// This exists purely to expose types used by other components. -namespace sync15 { - -}; - -/// Enumeration for the different types of device. -/// -/// Firefox Accounts separates devices into broad categories for display purposes, -/// such as distinguishing a desktop PC from a mobile phone. Upon signin, the -/// application should inspect the device it is running on and select an appropriate -/// [`DeviceType`] to include in its device registration record. -enum DeviceType { - "Desktop", - "Mobile", - "Tablet", - "VR", - "TV", - "Unknown", -}; diff --git a/components/sync15/src/telemetry.rs b/components/sync15/src/telemetry.rs index 6b0ab056eb..b550c8df1d 100644 --- a/components/sync15/src/telemetry.rs +++ b/components/sync15/src/telemetry.rs @@ -13,7 +13,7 @@ use crate::error::warn; use std::collections::HashMap; use std::time; -use serde::{ser, Serialize, Serializer}; +use serde::{Serialize, Serializer, ser}; // A test helper, used by the many test modules below. #[cfg(test)] @@ -439,7 +439,7 @@ impl Engine { pub fn incoming(&mut self, inc: EngineIncoming) { match &mut self.incoming { None => self.incoming = Some(inc), - Some(ref mut existing) => existing.accum(&inc), + Some(existing) => existing.accum(&inc), }; } @@ -764,10 +764,10 @@ impl SyncTelemetryPing { } pub fn uid(&mut self, uid: String) { - if let Some(ref existing) = self.uid { - if *existing != uid { - warn!("existing uid ${} being replaced by {}", existing, uid); - } + if let Some(ref existing) = self.uid + && *existing != uid + { + warn!("existing uid ${} being replaced by {}", existing, uid); } self.uid = Some(uid); } @@ -830,7 +830,7 @@ impl From<&Error> for SyncFailure { #[cfg(feature = "sync-client")] Error::BackoffError(_) => SyncFailure::Http { code: 503 }, #[cfg(feature = "sync-client")] - Error::StorageHttpError(ref e) => match e { + Error::StorageHttpError(e) => match e { ErrorResponse::NotFound { .. } => SyncFailure::Http { code: 404 }, ErrorResponse::Unauthorized { .. } => SyncFailure::Auth { from: "storage" }, ErrorResponse::PreconditionFailed { .. } => SyncFailure::Http { code: 412 }, @@ -838,16 +838,16 @@ impl From<&Error> for SyncFailure { ErrorResponse::RequestFailed { status, .. } => SyncFailure::Http { code: *status }, }, #[cfg(feature = "crypto")] - Error::CryptoError(ref e) => SyncFailure::Unexpected { + Error::CryptoError(e) => SyncFailure::Unexpected { error: e.to_string(), }, #[cfg(feature = "sync-client")] - Error::RequestError(ref e) => SyncFailure::Unexpected { + Error::RequestError(e) => SyncFailure::Unexpected { error: e.to_string(), }, #[cfg(feature = "sync-client")] - Error::UnexpectedStatus(ref e) => SyncFailure::Http { code: e.status }, - Error::Interrupted(ref e) => SyncFailure::Unexpected { + Error::UnexpectedStatus(e) => SyncFailure::Http { code: e.status }, + Error::Interrupted(e) => SyncFailure::Unexpected { error: e.to_string(), }, e => SyncFailure::Other { diff --git a/examples/sync-pass/src/sync-pass.rs b/examples/sync-pass/src/sync-pass.rs index 880d5030b8..1f57b76c8f 100644 --- a/examples/sync-pass/src/sync-pass.rs +++ b/examples/sync-pass/src/sync-pass.rs @@ -338,7 +338,10 @@ fn do_sync( }; let root_sync_key = &sync15::KeyBundle::from_ksync_base64(sync_key.as_str())?; - let mut disk_cached_state = engine.get_global_state()?; + // We don't track any state at all - this means every sync acts like a first sync. + // We should consider supporting this - choices would be to re-open the database ourself and abuse the + // meta tables, storing a disk on file, etc. + let mut disk_cached_state = None; let mut mem_cached_state = MemoryCachedState::default(); let mut result = sync_multiple( @@ -350,7 +353,8 @@ fn do_sync( &engine.scope, None, ); - engine.set_global_state(&disk_cached_state)?; + + // and here we should persist `disk_cached_state` somewhere. if let Err(e) = result.result { return Err(e.into());