зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1634257 - expose wipe_all to mozIExtensionStorageArea. r=lina
Differential Revision: https://phabricator.services.mozilla.com/D73191
This commit is contained in:
Родитель
c24a8d4f1f
Коммит
baecd41165
|
@ -1242,7 +1242,7 @@ checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-support"
|
name = "error-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"failure",
|
"failure",
|
||||||
]
|
]
|
||||||
|
@ -2180,7 +2180,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "interrupt-support"
|
name = "interrupt-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "intl-memoizer"
|
name = "intl-memoizer"
|
||||||
|
@ -3115,7 +3115,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nss_build_common"
|
name = "nss_build_common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nsstring"
|
name = "nsstring"
|
||||||
|
@ -4245,7 +4245,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sql-support"
|
name = "sql-support"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ffi-support",
|
"ffi-support",
|
||||||
"interrupt-support",
|
"interrupt-support",
|
||||||
|
@ -4442,7 +4442,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sync-guid"
|
name = "sync-guid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.0",
|
"base64 0.12.0",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -4453,7 +4453,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sync15-traits"
|
name = "sync15-traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"failure",
|
"failure",
|
||||||
"ffi-support",
|
"ffi-support",
|
||||||
|
@ -5168,7 +5168,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webext-storage"
|
name = "webext-storage"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/application-services?rev=775fc33603d722b75ff3579a5f2c52dbd4715b45#775fc33603d722b75ff3579a5f2c52dbd4715b45"
|
source = "git+https://github.com/mozilla/application-services?rev=d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7#d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-support",
|
"error-support",
|
||||||
"failure",
|
"failure",
|
||||||
|
|
|
@ -8,13 +8,13 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atomic_refcell = "0.1"
|
atomic_refcell = "0.1"
|
||||||
cstr = "0.1"
|
cstr = "0.1"
|
||||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "775fc33603d722b75ff3579a5f2c52dbd4715b45" }
|
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
moz_task = { path = "../../../xpcom/rust/moz_task" }
|
moz_task = { path = "../../../xpcom/rust/moz_task" }
|
||||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||||
storage_variant = { path = "../../../storage/variant" }
|
storage_variant = { path = "../../../storage/variant" }
|
||||||
sync15-traits = { git = "https://github.com/mozilla/application-services", rev = "775fc33603d722b75ff3579a5f2c52dbd4715b45" }
|
sync15-traits = { git = "https://github.com/mozilla/application-services", rev = "d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7" }
|
||||||
xpcom = { path = "../../../xpcom/rust/xpcom" }
|
xpcom = { path = "../../../xpcom/rust/xpcom" }
|
||||||
|
|
||||||
[dependencies.thin-vec]
|
[dependencies.thin-vec]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"files":{"Cargo.toml":"23ed53b7db21b1015cbb1deafe950f80068691dfe7f2256e9f9237a94910a4d8","README.md":"1fd617294339930ee1ad5172377648b268cce0216fc3971facbfe7c6839e9ab1","build.rs":"2b827a62155a3d724cdb4c198270ea467439e537403f82fa873321ac55a69a63","sql/create_schema.sql":"d50b22cb17fc5d4e2aa4d001e853bd2f67eb3ffdbb1ac29013067dceacaec80e","src/api.rs":"5413ccbf382cb13993ed31cfc62dd948b5c40404a6c513deed4238c5f8bc2bd5","src/db.rs":"8933ce788e1044aa654eb0ed177596e327057dd49001287d3fbfcf57cc6bb728","src/error.rs":"86ba215ec5a889d1ccca9dcd141e42f75914744a4803598ccf3894da4a7f7475","src/lib.rs":"14dfeb708dfa78c916d85818fc21af24cbdc05748c8d21c2f7d82a22a4f5cc14","src/schema.rs":"ac475285fb065fdf639d71e34d4e12663eb0650eefe3e151d223eb4fe3a667ef","src/store.rs":"83ab13bd6bb9fcc60705441580acd26b06030ad6599de1b306eee7541b742e89"},"package":null}
|
{"files":{"Cargo.toml":"23ed53b7db21b1015cbb1deafe950f80068691dfe7f2256e9f9237a94910a4d8","README.md":"1fd617294339930ee1ad5172377648b268cce0216fc3971facbfe7c6839e9ab1","build.rs":"2b827a62155a3d724cdb4c198270ea467439e537403f82fa873321ac55a69a63","sql/create_schema.sql":"d50b22cb17fc5d4e2aa4d001e853bd2f67eb3ffdbb1ac29013067dceacaec80e","src/api.rs":"578862ecc35d1bfa0c96329702cc7ffd743d749a170d808a729f91f584b33b3d","src/db.rs":"8933ce788e1044aa654eb0ed177596e327057dd49001287d3fbfcf57cc6bb728","src/error.rs":"86ba215ec5a889d1ccca9dcd141e42f75914744a4803598ccf3894da4a7f7475","src/lib.rs":"79685854649ffd0c1664f67cd0264f86c93f49e974de217a94a005b9d9d1c39d","src/schema.rs":"ac475285fb065fdf639d71e34d4e12663eb0650eefe3e151d223eb4fe3a667ef","src/store.rs":"686003abb14ffd1ef06f8a09a74c463ffaaf8e283ae7b92809122806e7085013"},"package":null}
|
|
@ -253,6 +253,21 @@ pub fn clear(tx: &Transaction<'_>, ext_id: &str) -> Result<StorageChanges> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// While this API isn't available to extensions, Firefox wants a way to wipe
|
||||||
|
/// all data for all addons but not sync the deletions. We also don't report
|
||||||
|
/// the changes caused by the deletion.
|
||||||
|
/// That means that after doing this, the next sync is likely to drag some data
|
||||||
|
/// back in - which is fine.
|
||||||
|
/// This is much like what the sync support for other components calls a "wipe",
|
||||||
|
/// so we name it similarly.
|
||||||
|
pub fn wipe_all(tx: &Transaction<'_>) -> Result<()> {
|
||||||
|
// We assume the meta table is only used by sync.
|
||||||
|
tx.execute_batch(
|
||||||
|
"DELETE FROM storage_sync_data; DELETE FROM storage_sync_mirror; DELETE FROM meta;",
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// TODO - get_bytes_in_use()
|
// TODO - get_bytes_in_use()
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -488,4 +503,37 @@ mod tests {
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn query_count(conn: &Connection, table: &str) -> u32 {
|
||||||
|
conn.query_row_and_then(
|
||||||
|
&format!("SELECT COUNT(*) FROM {};", table),
|
||||||
|
rusqlite::NO_PARAMS,
|
||||||
|
|row| row.get::<_, u32>(0),
|
||||||
|
)
|
||||||
|
.expect("should work")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wipe() -> Result<()> {
|
||||||
|
use crate::db::put_meta;
|
||||||
|
|
||||||
|
let mut db = new_mem_db();
|
||||||
|
let tx = db.transaction()?;
|
||||||
|
set(&tx, "ext-a", json!({ "x": "y" }))?;
|
||||||
|
set(&tx, "ext-b", json!({ "y": "x" }))?;
|
||||||
|
put_meta(&tx, "meta", &"meta-meta".to_string())?;
|
||||||
|
tx.execute(
|
||||||
|
"INSERT INTO storage_sync_mirror (guid, ext_id, data)
|
||||||
|
VALUES ('guid', 'ext-a', null)",
|
||||||
|
rusqlite::NO_PARAMS,
|
||||||
|
)?;
|
||||||
|
assert_eq!(query_count(&tx, "storage_sync_data"), 2);
|
||||||
|
assert_eq!(query_count(&tx, "storage_sync_mirror"), 1);
|
||||||
|
assert_eq!(query_count(&tx, "meta"), 1);
|
||||||
|
wipe_all(&tx)?;
|
||||||
|
assert_eq!(query_count(&tx, "storage_sync_data"), 0);
|
||||||
|
assert_eq!(query_count(&tx, "storage_sync_mirror"), 0);
|
||||||
|
assert_eq!(query_count(&tx, "meta"), 0);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,7 @@ pub fn delme_demo_usage() -> error::Result<()> {
|
||||||
store.get("ext-id", json!({}))?;
|
store.get("ext-id", json!({}))?;
|
||||||
store.remove("ext-id", json!({}))?;
|
store.remove("ext-id", json!({}))?;
|
||||||
store.clear("ext-id")?;
|
store.clear("ext-id")?;
|
||||||
|
// and it might even...
|
||||||
|
store.wipe_all()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,15 @@ impl Store {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wipe all local data without syncing or returning any information about
|
||||||
|
/// the deletion.
|
||||||
|
pub fn wipe_all(&self) -> Result<()> {
|
||||||
|
let tx = self.db.unchecked_transaction()?;
|
||||||
|
api::wipe_all(&tx)?;
|
||||||
|
tx.commit()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Closes the store and its database connection. See the docs for
|
/// Closes the store and its database connection. See the docs for
|
||||||
/// `StorageDb::close` for more details on when this can fail.
|
/// `StorageDb::close` for more details on when this can fail.
|
||||||
pub fn close(self) -> result::Result<(), (Store, Error)> {
|
pub fn close(self) -> result::Result<(), (Store, Error)> {
|
||||||
|
|
|
@ -41,6 +41,11 @@ interface mozIExtensionStorageArea : nsISupports {
|
||||||
// method will be called with all removed key-value pairs.
|
// method will be called with all removed key-value pairs.
|
||||||
void clear(in AUTF8String extensionId,
|
void clear(in AUTF8String extensionId,
|
||||||
in mozIExtensionStorageCallback callback);
|
in mozIExtensionStorageCallback callback);
|
||||||
|
|
||||||
|
// Wipes all data from the storage area for all extensions. The deletion
|
||||||
|
// will not be synced, and no callback facility is provided for notification
|
||||||
|
// of the deletions.
|
||||||
|
void wipeAll(in mozIExtensionStorageCallback callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A configurable storage area has additional methods for setting up and tearing
|
// A configurable storage area has additional methods for setting up and tearing
|
||||||
|
|
|
@ -16,4 +16,4 @@ xpcom = { path = "../../../../../xpcom/rust/xpcom" }
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
storage_variant = { path = "../../../../../storage/variant" }
|
storage_variant = { path = "../../../../../storage/variant" }
|
||||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "775fc33603d722b75ff3579a5f2c52dbd4715b45" }
|
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7" }
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl StorageSyncArea {
|
||||||
callback: *const mozIExtensionStorageCallback
|
callback: *const mozIExtensionStorageCallback
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
/// Removes all keys and values.
|
/// Removes all keys and values for the specified extension.
|
||||||
fn clear(&self, ext_id: &nsACString, callback: &mozIExtensionStorageCallback) -> Result<()> {
|
fn clear(&self, ext_id: &nsACString, callback: &mozIExtensionStorageCallback) -> Result<()> {
|
||||||
self.dispatch(
|
self.dispatch(
|
||||||
StorageOp::Clear {
|
StorageOp::Clear {
|
||||||
|
@ -186,6 +186,16 @@ impl StorageSyncArea {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xpcom_method!(
|
||||||
|
wipe_all => WipeAll(
|
||||||
|
callback: *const mozIExtensionStorageCallback
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/// Removes all keys and values for all extensions.
|
||||||
|
fn wipe_all(&self, callback: &mozIExtensionStorageCallback) -> Result<()> {
|
||||||
|
self.dispatch(StorageOp::WipeAll, callback)
|
||||||
|
}
|
||||||
|
|
||||||
xpcom_method!(teardown => Teardown(callback: *const mozIExtensionStorageCallback));
|
xpcom_method!(teardown => Teardown(callback: *const mozIExtensionStorageCallback));
|
||||||
/// Tears down the storage area, closing the backing database connection.
|
/// Tears down the storage area, closing the backing database connection.
|
||||||
fn teardown(&self, callback: &mozIExtensionStorageCallback) -> Result<()> {
|
fn teardown(&self, callback: &mozIExtensionStorageCallback) -> Result<()> {
|
||||||
|
|
|
@ -34,6 +34,8 @@ pub enum StorageOp {
|
||||||
Remove { ext_id: String, keys: JsonValue },
|
Remove { ext_id: String, keys: JsonValue },
|
||||||
/// Clear all keys and values for an extension.
|
/// Clear all keys and values for an extension.
|
||||||
Clear { ext_id: String },
|
Clear { ext_id: String },
|
||||||
|
/// Clear all keys and values for all extensions.
|
||||||
|
WipeAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StorageOp {
|
impl StorageOp {
|
||||||
|
@ -45,6 +47,7 @@ impl StorageOp {
|
||||||
StorageOp::Set { .. } => "webext_storage::set",
|
StorageOp::Set { .. } => "webext_storage::set",
|
||||||
StorageOp::Remove { .. } => "webext_storage::remove",
|
StorageOp::Remove { .. } => "webext_storage::remove",
|
||||||
StorageOp::Clear { .. } => "webext_storage::clear",
|
StorageOp::Clear { .. } => "webext_storage::clear",
|
||||||
|
StorageOp::WipeAll => "webext_storage::wipe_all",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,6 +146,10 @@ impl StorageTask {
|
||||||
StorageOp::Clear { ext_id } => {
|
StorageOp::Clear { ext_id } => {
|
||||||
StorageResult::with_changes(self.store()?.get()?.clear(&ext_id)?)
|
StorageResult::with_changes(self.store()?.get()?.clear(&ext_id)?)
|
||||||
}
|
}
|
||||||
|
StorageOp::WipeAll => {
|
||||||
|
self.store()?.get()?.wipe_all()?;
|
||||||
|
Ok(StorageResult::default())
|
||||||
|
}
|
||||||
}?)
|
}?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,5 +89,29 @@ add_task(
|
||||||
"`get` without a key should return all values"
|
"`get` without a key should return all values"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
await promisify(
|
||||||
|
service.set,
|
||||||
|
"ext-2",
|
||||||
|
JSON.stringify({
|
||||||
|
hi: "hola! 👋",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await promisify(service.clear, "ext-1");
|
||||||
|
let { value: allValues } = await promisify(service.get, "ext-1", "null");
|
||||||
|
deepEqual(allValues, {}, "clear removed ext-1");
|
||||||
|
|
||||||
|
let { value: allValues2 } = await promisify(service.get, "ext-2", "null");
|
||||||
|
deepEqual(allValues2, { hi: "hola! 👋" }, "clear didn't remove ext-2");
|
||||||
|
|
||||||
|
await promisify(service.wipeAll);
|
||||||
|
|
||||||
|
deepEqual(
|
||||||
|
(await promisify(service.get, "ext-2", "null")).value,
|
||||||
|
{},
|
||||||
|
"wipeAll removed ext-2"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -54,7 +54,7 @@ unic-langid = { version = "0.8", features = ["likelysubtags"] }
|
||||||
unic-langid-ffi = { path = "../../../../intl/locale/rust/unic-langid-ffi" }
|
unic-langid-ffi = { path = "../../../../intl/locale/rust/unic-langid-ffi" }
|
||||||
fluent-langneg = { version = "0.12.1", features = ["cldr"] }
|
fluent-langneg = { version = "0.12.1", features = ["cldr"] }
|
||||||
fluent-langneg-ffi = { path = "../../../../intl/locale/rust/fluent-langneg-ffi" }
|
fluent-langneg-ffi = { path = "../../../../intl/locale/rust/fluent-langneg-ffi" }
|
||||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "775fc33603d722b75ff3579a5f2c52dbd4715b45", optional = true }
|
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "d8a50bb0b010ab7289fe2d2864cc3eb9687a52e7", optional = true }
|
||||||
golden_gate = { path = "../../../../services/sync/golden_gate", optional = true }
|
golden_gate = { path = "../../../../services/sync/golden_gate", optional = true }
|
||||||
|
|
||||||
# Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
|
# Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
|
||||||
|
|
Загрузка…
Ссылка в новой задаче