diff --git a/services/crypto/modules/WeaveCrypto.js b/services/crypto/modules/WeaveCrypto.js index 1e834ad0e17..2252d9f39e4 100644 --- a/services/crypto/modules/WeaveCrypto.js +++ b/services/crypto/modules/WeaveCrypto.js @@ -419,6 +419,17 @@ WeaveCrypto.prototype = { this.nss.PK11_FreeSlot = nsslib.declare("PK11_FreeSlot", ctypes.default_abi, ctypes.void_t, this.nss_t.PK11SlotInfo.ptr); + // security/nss/lib/util/secitem.h#49 + // extern SECItem *SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len); + this.nss.SECITEM_AllocItem = nsslib.declare("SECITEM_AllocItem", + ctypes.default_abi, this.nss_t.SECItem.ptr, + this.nss_t.PLArenaPool.ptr, // Not used. + this.nss_t.SECItem.ptr, ctypes.unsigned_int); + // security/nss/lib/util/secitem.h#274 + // extern void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit); + this.nss.SECITEM_ZfreeItem = nsslib.declare("SECITEM_ZfreeItem", + ctypes.default_abi, ctypes.void_t, + this.nss_t.SECItem.ptr, this.nss_t.PRBool); // security/nss/lib/util/secitem.h#114 // extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit); this.nss.SECITEM_FreeItem = nsslib.declare("SECITEM_FreeItem", @@ -515,7 +526,7 @@ WeaveCrypto.prototype = { let ctx, symKey, slot, ivParam; try { - ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address()); + ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem); if (ivParam.isNull()) throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE); @@ -523,7 +534,7 @@ WeaveCrypto.prototype = { if (slot.isNull()) throw Components.Exception("can't get internal key slot", Cr.NS_ERROR_FAILURE); - symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null); + symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem, null); if (symKey.isNull()) throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE); @@ -563,6 +574,8 @@ WeaveCrypto.prototype = { this.nss.PK11_FreeSlot(slot); if (ivParam && !ivParam.isNull()) this.nss.SECITEM_FreeItem(ivParam, true); + this.freeSECItem(keyItem); + this.freeSECItem(ivItem); } }, @@ -684,15 +697,28 @@ WeaveCrypto.prototype = { return btoa(this.expandData(data, len)); }, + // Returns a filled SECItem *, as returned by SECITEM_AllocItem. + // + // Note that this must be released with freeSECItem, which will also + // deallocate the internal buffer. makeSECItem : function(input, isEncoded) { if (isEncoded) input = atob(input); - let outputData = new ctypes.ArrayType(ctypes.unsigned_char, input.length)(); - this.byteCompress(input, outputData); - - return new this.nss_t.SECItem(this.nss.SIBUFFER, outputData, outputData.length); + + let len = input.length; + let item = this.nss.SECITEM_AllocItem(null, null, len); + if (item.isNull()) + throw "SECITEM_AllocItem failed."; + + let dest = ctypes.cast(item.contents.data, ctypes.unsigned_char.array(len).ptr); + this.byteCompress(input, dest.contents); + return item; + }, + + freeSECItem : function(zap) { + if (zap && !zap.isNull()) + this.nss.SECITEM_ZfreeItem(zap, true); }, - /** * Returns the expanded data string for the derived key. @@ -712,7 +738,8 @@ WeaveCrypto.prototype = { let algid, slot, symKey, keyData; try { algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg, - keyLength, iterations, saltItem.address()); + keyLength, iterations, + saltItem); if (algid.isNull()) throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); @@ -720,7 +747,7 @@ WeaveCrypto.prototype = { if (slot.isNull()) throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); - symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null); + symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem, false, null); if (symKey.isNull()) throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); @@ -748,6 +775,9 @@ WeaveCrypto.prototype = { this.nss.PK11_FreeSlot(slot); if (symKey && !symKey.isNull()) this.nss.PK11_FreeSymKey(symKey); - } + + this.freeSECItem(passItem); + this.freeSECItem(saltItem); + } }, }; diff --git a/services/crypto/tests/unit/test_crypto_crypt.js b/services/crypto/tests/unit/test_crypto_crypt.js index dc53002dab7..c8cc41af517 100644 --- a/services/crypto/tests/unit/test_crypto_crypt.js +++ b/services/crypto/tests/unit/test_crypto_crypt.js @@ -8,7 +8,50 @@ try { .getService(Ci.IWeaveCrypto); } +function multiple_decrypts(iterations) { + let iv = cryptoSvc.generateRandomIV(); + let key = cryptoSvc.generateRandomKey(); + let cipherText = cryptoSvc.encrypt("Hello, world.", key, iv); + + for (let i = 0; i < iterations; ++i) { + let clearText = cryptoSvc.decrypt(cipherText, key, iv); + do_check_eq(clearText + " " + i, "Hello, world. " + i); + } + _("Done with multiple_decrypts."); +} + +function test_bug_617650() { + if (this.gczeal) { + gczeal(2); + // Few iterations, because gczeal(2) is expensive... and makes it fail much faster! + _("gczeal set to 2; attempting 10 iterations of multiple_decrypts."); + multiple_decrypts(10); + gczeal(0); + } else { + // We can't use gczeal on non-debug builds, so try lots of reps instead. + _("No gczeal (non-debug build?); attempting 10,000 iterations of multiple_decrypts."); + multiple_decrypts(10000); + } +} + +// Just verify that it gets populated with the correct bytes. +function test_makeSECItem() { + Components.utils.import("resource://gre/modules/ctypes.jsm"); + + let item1 = cryptoSvc.makeSECItem("abcdefghi", false); + do_check_true(!item1.isNull()); + let intData = ctypes.cast(item1.contents.data, ctypes.uint8_t.array(8).ptr).contents; + for (let i = 0; i < 8; ++i) + do_check_eq(intData[i], "abcdefghi".charCodeAt(i)); +} + function run_test() { + + if ("makeSECItem" in cryptoSvc) // Only for js-ctypes WeaveCrypto. + test_makeSECItem(); + + test_bug_617650(); + // First, do a normal run with expected usage... Generate a random key and // iv, encrypt and decrypt a string. var iv = cryptoSvc.generateRandomIV(); diff --git a/services/sync/modules/auth.js b/services/sync/modules/auth.js deleted file mode 100644 index 9bbfd55f0b5..00000000000 --- a/services/sync/modules/auth.js +++ /dev/null @@ -1,101 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['Auth', 'BrokenBasicAuthenticator', - 'BasicAuthenticator', 'NoOpAuthenticator']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/util.js"); - -Utils.lazy(this, 'Auth', AuthMgr); - -// XXX: the authenticator api will probably need to be changed to support -// other methods (digest, oauth, etc) - -function NoOpAuthenticator() {} -NoOpAuthenticator.prototype = { - onRequest: function NoOpAuth_onRequest(headers) { - return headers; - } -}; - -// Warning: This will drop the high unicode bytes from passwords. -// Use BasicAuthenticator to send non-ASCII passwords UTF8-encoded. -function BrokenBasicAuthenticator(identity) { - this._id = identity; -} -BrokenBasicAuthenticator.prototype = { - onRequest: function BasicAuth_onRequest(headers) { - headers['Authorization'] = 'Basic ' + - btoa(this._id.username + ':' + this._id.password); - return headers; - } -}; - -function BasicAuthenticator(identity) { - this._id = identity; -} -BasicAuthenticator.prototype = { - onRequest: function onRequest(headers) { - headers['Authorization'] = 'Basic ' + - btoa(this._id.username + ':' + this._id.passwordUTF8); - return headers; - } -}; - -function AuthMgr() { - this._authenticators = {}; - this.defaultAuthenticator = new NoOpAuthenticator(); -} -AuthMgr.prototype = { - defaultAuthenticator: null, - - registerAuthenticator: function AuthMgr_register(match, authenticator) { - this._authenticators[match] = authenticator; - }, - - lookupAuthenticator: function AuthMgr_lookup(uri) { - for (let match in this._authenticators) { - if (uri.match(match)) - return this._authenticators[match]; - } - return this.defaultAuthenticator; - } -}; diff --git a/services/sync/modules/base_records/collection.js b/services/sync/modules/base_records/collection.js deleted file mode 100644 index 64aa4790e8f..00000000000 --- a/services/sync/modules/base_records/collection.js +++ /dev/null @@ -1,158 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['Collection']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/resource.js"); -Cu.import("resource://services-sync/util.js"); - -function Collection(uri, recordObj) { - Resource.call(this, uri); - this._recordObj = recordObj; - - this._full = false; - this._ids = null; - this._limit = 0; - this._older = 0; - this._newer = 0; - this._data = []; -} -Collection.prototype = { - __proto__: Resource.prototype, - _logName: "Collection", - - _rebuildURL: function Coll__rebuildURL() { - // XXX should consider what happens if it's not a URL... - this.uri.QueryInterface(Ci.nsIURL); - - let args = []; - if (this.older) - args.push('older=' + this.older); - else if (this.newer) { - args.push('newer=' + this.newer); - } - if (this.full) - args.push('full=1'); - if (this.sort) - args.push('sort=' + this.sort); - if (this.ids != null) - args.push("ids=" + this.ids); - if (this.limit > 0 && this.limit != Infinity) - args.push("limit=" + this.limit); - - this.uri.query = (args.length > 0)? '?' + args.join('&') : ''; - }, - - // get full items - get full() { return this._full; }, - set full(value) { - this._full = value; - this._rebuildURL(); - }, - - // Apply the action to a certain set of ids - get ids() this._ids, - set ids(value) { - this._ids = value; - this._rebuildURL(); - }, - - // Limit how many records to get - get limit() this._limit, - set limit(value) { - this._limit = value; - this._rebuildURL(); - }, - - // get only items modified before some date - get older() { return this._older; }, - set older(value) { - this._older = value; - this._rebuildURL(); - }, - - // get only items modified since some date - get newer() { return this._newer; }, - set newer(value) { - this._newer = value; - this._rebuildURL(); - }, - - // get items sorted by some criteria. valid values: - // oldest (oldest first) - // newest (newest first) - // index - get sort() { return this._sort; }, - set sort(value) { - this._sort = value; - this._rebuildURL(); - }, - - pushData: function Coll_pushData(data) { - this._data.push(data); - }, - - clearRecords: function Coll_clearRecords() { - this._data = []; - }, - - set recordHandler(onRecord) { - // Save this because onProgress is called with this as the ChannelListener - let coll = this; - - // Switch to newline separated records for incremental parsing - coll.setHeader("Accept", "application/newlines"); - - this._onProgress = function() { - let newline; - while ((newline = this._data.indexOf("\n")) > 0) { - // Split the json record from the rest of the data - let json = this._data.slice(0, newline); - this._data = this._data.slice(newline + 1); - - // Deserialize a record from json and give it to the callback - let record = new coll._recordObj(); - record.deserialize(json); - onRecord(record); - } - }; - } -}; diff --git a/services/sync/modules/base_records/wbo.js b/services/sync/modules/base_records/wbo.js deleted file mode 100644 index eb719b33764..00000000000 --- a/services/sync/modules/base_records/wbo.js +++ /dev/null @@ -1,174 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * Richard Newman - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['WBORecord', 'RecordManager', 'Records']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/log4moz.js"); -Cu.import("resource://services-sync/resource.js"); -Cu.import("resource://services-sync/util.js"); - -function WBORecord(collection, id) { - this.data = {}; - this.payload = {}; - this.collection = collection; // Optional. - this.id = id; // Optional. -} -WBORecord.prototype = { - _logName: "Record.WBO", - - get sortindex() { - if (this.data.sortindex) - return this.data.sortindex; - return 0; - }, - - // Get thyself from your URI, then deserialize. - // Set thine 'response' field. - fetch: function fetch(uri) { - let r = new Resource(uri).get(); - if (r.success) { - this.deserialize(r); // Warning! Muffles exceptions! - } - this.response = r; - return this; - }, - - upload: function upload(uri) { - return new Resource(uri).put(this); - }, - - // Take a base URI string, with trailing slash, and return the URI of this - // WBO based on collection and ID. - uri: function(base) { - if (this.collection && this.id) - return Utils.makeURL(base + this.collection + "/" + this.id); - return null; - }, - - deserialize: function deserialize(json) { - this.data = json.constructor.toString() == String ? JSON.parse(json) : json; - - try { - // The payload is likely to be JSON, but if not, keep it as a string - this.payload = JSON.parse(this.payload); - } catch(ex) {} - }, - - toJSON: function toJSON() { - // Copy fields from data to be stringified, making sure payload is a string - let obj = {}; - for (let [key, val] in Iterator(this.data)) - obj[key] = key == "payload" ? JSON.stringify(val) : val; - if (this.ttl) - obj.ttl = this.ttl; - return obj; - }, - - toString: function WBORec_toString() "{ " + [ - "id: " + this.id, - "index: " + this.sortindex, - "modified: " + this.modified, - "ttl: " + this.ttl, - "payload: " + JSON.stringify(this.payload) - ].join("\n ") + " }", -}; - -Utils.deferGetSet(WBORecord, "data", ["id", "modified", "sortindex", "payload"]); - -Utils.lazy(this, 'Records', RecordManager); - -function RecordManager() { - this._log = Log4Moz.repository.getLogger(this._logName); - this._records = {}; -} -RecordManager.prototype = { - _recordType: WBORecord, - _logName: "RecordMgr", - - import: function RecordMgr_import(url) { - this._log.trace("Importing record: " + (url.spec ? url.spec : url)); - try { - // Clear out the last response with empty object if GET fails - this.response = {}; - this.response = new Resource(url).get(); - - // Don't parse and save the record on failure - if (!this.response.success) - return null; - - let record = new this._recordType(url); - record.deserialize(this.response); - - return this.set(url, record); - } catch(ex) { - this._log.debug("Failed to import record: " + Utils.exceptionStr(ex)); - return null; - } - }, - - get: function RecordMgr_get(url) { - // Use a url string as the key to the hash - let spec = url.spec ? url.spec : url; - if (spec in this._records) - return this._records[spec]; - return this.import(url); - }, - - set: function RecordMgr_set(url, record) { - let spec = url.spec ? url.spec : url; - return this._records[spec] = record; - }, - - contains: function RecordMgr_contains(url) { - if ((url.spec || url) in this._records) - return true; - return false; - }, - - clearCache: function recordMgr_clearCache() { - this._records = {}; - }, - - del: function RecordMgr_del(url) { - delete this._records[url]; - } -}; diff --git a/services/sync/modules/engines.js b/services/sync/modules/engines.js index b56d006bb81..8d31d8772b7 100644 --- a/services/sync/modules/engines.js +++ b/services/sync/modules/engines.js @@ -20,6 +20,7 @@ * Contributor(s): * Dan Mills * Myk Melez + * Anant Narayanan * Philipp von Weitershausen * Richard Newman * @@ -37,28 +38,206 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['Engines', 'Engine', 'SyncEngine']; +const EXPORTED_SYMBOLS = ['Engines', 'Engine', 'SyncEngine', + 'Tracker', 'Store']; const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; const Cu = Components.utils; -Cu.import("resource://services-sync/base_records/collection.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/ext/Observers.js"); Cu.import("resource://services-sync/ext/Sync.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/resource.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/main.js"); // So we can get to Service for callbacks. +/* + * Trackers are associated with a single engine and deal with + * listening for changes to their particular data type. + * + * There are two things they keep track of: + * 1) A score, indicating how urgently the engine wants to sync + * 2) A list of IDs for all the changed items that need to be synced + * and updating their 'score', indicating how urgently they + * want to sync. + * + */ +function Tracker(name) { + name = name || "Unnamed"; + this.name = this.file = name.toLowerCase(); + + this._log = Log4Moz.repository.getLogger("Tracker." + name); + let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); + this._log.level = Log4Moz.Level[level]; + + this._score = 0; + this._ignored = []; + this.ignoreAll = false; + this.changedIDs = {}; + this.loadChangedIDs(); +} +Tracker.prototype = { + /* + * Score can be called as often as desired to decide which engines to sync + * + * Valid values for score: + * -1: Do not sync unless the user specifically requests it (almost disabled) + * 0: Nothing has changed + * 100: Please sync me ASAP! + * + * Setting it to other values should (but doesn't currently) throw an exception + */ + get score() { + return this._score; + }, + + set score(value) { + this._score = value; + Observers.notify("weave:engine:score:updated", this.name); + }, + + // Should be called by service everytime a sync has been done for an engine + resetScore: function T_resetScore() { + this._score = 0; + }, + + saveChangedIDs: function T_saveChangedIDs() { + Utils.delay(function() { + Utils.jsonSave("changes/" + this.file, this, this.changedIDs); + }, 1000, this, "_lazySave"); + }, + + loadChangedIDs: function T_loadChangedIDs() { + Utils.jsonLoad("changes/" + this.file, this, function(json) { + this.changedIDs = json; + }); + }, + + // ignore/unignore specific IDs. Useful for ignoring items that are + // being processed, or that shouldn't be synced. + // But note: not persisted to disk + + ignoreID: function T_ignoreID(id) { + this.unignoreID(id); + this._ignored.push(id); + }, + + unignoreID: function T_unignoreID(id) { + let index = this._ignored.indexOf(id); + if (index != -1) + this._ignored.splice(index, 1); + }, + + addChangedID: function addChangedID(id, when) { + if (!id) { + this._log.warn("Attempted to add undefined ID to tracker"); + return false; + } + if (this.ignoreAll || (id in this._ignored)) + return false; + + // Default to the current time in seconds if no time is provided + if (when == null) + when = Math.floor(Date.now() / 1000); + + // Add/update the entry if we have a newer time + if ((this.changedIDs[id] || -Infinity) < when) { + this._log.trace("Adding changed ID: " + [id, when]); + this.changedIDs[id] = when; + this.saveChangedIDs(); + } + return true; + }, + + removeChangedID: function T_removeChangedID(id) { + if (!id) { + this._log.warn("Attempted to remove undefined ID to tracker"); + return false; + } + if (this.ignoreAll || (id in this._ignored)) + return false; + if (this.changedIDs[id] != null) { + this._log.trace("Removing changed ID " + id); + delete this.changedIDs[id]; + this.saveChangedIDs(); + } + return true; + }, + + clearChangedIDs: function T_clearChangedIDs() { + this._log.trace("Clearing changed ID list"); + this.changedIDs = {}; + this.saveChangedIDs(); + } +}; + + + +/* + * Data Stores + * These can wrap, serialize items and apply commands + */ + +function Store(name) { + name = name || "Unnamed"; + this.name = name.toLowerCase(); + + this._log = Log4Moz.repository.getLogger("Store." + name); + let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); + this._log.level = Log4Moz.Level[level]; +} +Store.prototype = { + applyIncoming: function Store_applyIncoming(record) { + if (record.deleted) + this.remove(record); + else if (!this.itemExists(record.id)) + this.create(record); + else + this.update(record); + }, + + // override these in derived objects + + create: function Store_create(record) { + throw "override create in a subclass"; + }, + + remove: function Store_remove(record) { + throw "override remove in a subclass"; + }, + + update: function Store_update(record) { + throw "override update in a subclass"; + }, + + itemExists: function Store_itemExists(id) { + throw "override itemExists in a subclass"; + }, + + createRecord: function Store_createRecord(id, collection) { + throw "override createRecord in a subclass"; + }, + + changeItemID: function Store_changeItemID(oldID, newID) { + throw "override changeItemID in a subclass"; + }, + + getAllIDs: function Store_getAllIDs() { + throw "override getAllIDs in a subclass"; + }, + + wipe: function Store_wipe() { + throw "override wipe in a subclass"; + } +}; + + // Singleton service, holds registered engines Utils.lazy(this, 'Engines', EngineManagerSvc); diff --git a/services/sync/modules/engines/bookmarks.js b/services/sync/modules/engines/bookmarks.js index feeaeb1b52f..287e8444a5c 100644 --- a/services/sync/modules/engines/bookmarks.js +++ b/services/sync/modules/engines/bookmarks.js @@ -38,7 +38,9 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['BookmarksEngine', 'BookmarksSharingManager']; +const EXPORTED_SYMBOLS = ['BookmarksEngine', "PlacesItem", "Bookmark", + "BookmarkFolder", "BookmarkMicsum", "BookmarkQuery", + "Livemark", "BookmarkSeparator"]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -57,11 +59,116 @@ catch(ex) { } Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/bookmark.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); + +function PlacesItem(collection, id, type) { + CryptoWrapper.call(this, collection, id); + this.type = type || "item"; +} +PlacesItem.prototype = { + decrypt: function PlacesItem_decrypt() { + // Do the normal CryptoWrapper decrypt, but change types before returning + let clear = CryptoWrapper.prototype.decrypt.apply(this, arguments); + + // Convert the abstract places item to the actual object type + if (!this.deleted) + this.__proto__ = this.getTypeObject(this.type).prototype; + + return clear; + }, + + getTypeObject: function PlacesItem_getTypeObject(type) { + switch (type) { + case "bookmark": + return Bookmark; + case "microsummary": + return BookmarkMicsum; + case "query": + return BookmarkQuery; + case "folder": + return BookmarkFolder; + case "livemark": + return Livemark; + case "separator": + return BookmarkSeparator; + case "item": + return PlacesItem; + } + throw "Unknown places item object type: " + type; + }, + + __proto__: CryptoWrapper.prototype, + _logName: "Record.PlacesItem", +}; + +Utils.deferGetSet(PlacesItem, "cleartext", ["hasDupe", "parentid", "parentName", + "type"]); + +function Bookmark(collection, id, type) { + PlacesItem.call(this, collection, id, type || "bookmark"); +} +Bookmark.prototype = { + __proto__: PlacesItem.prototype, + _logName: "Record.Bookmark", +}; + +Utils.deferGetSet(Bookmark, "cleartext", ["title", "bmkUri", "description", + "loadInSidebar", "tags", "keyword"]); + +function BookmarkMicsum(collection, id) { + Bookmark.call(this, collection, id, "microsummary"); +} +BookmarkMicsum.prototype = { + __proto__: Bookmark.prototype, + _logName: "Record.BookmarkMicsum", +}; + +Utils.deferGetSet(BookmarkMicsum, "cleartext", ["generatorUri", "staticTitle"]); + +function BookmarkQuery(collection, id) { + Bookmark.call(this, collection, id, "query"); +} +BookmarkQuery.prototype = { + __proto__: Bookmark.prototype, + _logName: "Record.BookmarkQuery", +}; + +Utils.deferGetSet(BookmarkQuery, "cleartext", ["folderName"]); + +function BookmarkFolder(collection, id, type) { + PlacesItem.call(this, collection, id, type || "folder"); +} +BookmarkFolder.prototype = { + __proto__: PlacesItem.prototype, + _logName: "Record.Folder", +}; + +Utils.deferGetSet(BookmarkFolder, "cleartext", ["description", "title", + "children"]); + +function Livemark(collection, id) { + BookmarkFolder.call(this, collection, id, "livemark"); +} +Livemark.prototype = { + __proto__: BookmarkFolder.prototype, + _logName: "Record.Livemark", +}; + +Utils.deferGetSet(Livemark, "cleartext", ["siteUri", "feedUri"]); + +function BookmarkSeparator(collection, id) { + PlacesItem.call(this, collection, id, "separator"); +} +BookmarkSeparator.prototype = { + __proto__: PlacesItem.prototype, + _logName: "Record.Separator", +}; + +Utils.deferGetSet(BookmarkSeparator, "cleartext", "pos"); + + function archiveBookmarks() { // Some nightly builds of 3.7 don't have this function try { diff --git a/services/sync/modules/engines/clients.js b/services/sync/modules/engines/clients.js index 02d35eb8f06..24748338c41 100644 --- a/services/sync/modules/engines/clients.js +++ b/services/sync/modules/engines/clients.js @@ -19,6 +19,7 @@ * * Contributor(s): * Dan Mills + * Philipp von Weitershausen * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -34,7 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ["Clients"]; +const EXPORTED_SYMBOLS = ["Clients", "ClientsRec"]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -43,12 +44,24 @@ const Cu = Components.utils; Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/ext/StringBundle.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/type_records/clients.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); +const CLIENTS_TTL = 1814400; // 21 days const CLIENTS_TTL_REFRESH = 604800; // 7 days +function ClientsRec(collection, id) { + CryptoWrapper.call(this, collection, id); +} +ClientsRec.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.Clients", + ttl: CLIENTS_TTL +}; + +Utils.deferGetSet(ClientsRec, "cleartext", ["name", "type", "commands"]); + + Utils.lazy(this, "Clients", ClientEngine); function ClientEngine() { diff --git a/services/sync/modules/engines/forms.js b/services/sync/modules/engines/forms.js index ba307802815..8bb5ebd5cf9 100644 --- a/services/sync/modules/engines/forms.js +++ b/services/sync/modules/engines/forms.js @@ -34,7 +34,7 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['FormEngine']; +const EXPORTED_SYMBOLS = ['FormEngine', 'FormRec']; const Cc = Components.classes; const Ci = Components.interfaces; @@ -42,12 +42,24 @@ const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/forms.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/log4moz.js"); +const FORMS_TTL = 5184000; // 60 days + +function FormRec(collection, id) { + CryptoWrapper.call(this, collection, id); +} +FormRec.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.Form", + ttl: FORMS_TTL +}; + +Utils.deferGetSet(FormRec, "cleartext", ["name", "value"]); + + let FormWrapper = { _log: Log4Moz.repository.getLogger('Engine.Forms'), diff --git a/services/sync/modules/engines/history.js b/services/sync/modules/engines/history.js index 56321ae6d8b..7df342b4dfa 100644 --- a/services/sync/modules/engines/history.js +++ b/services/sync/modules/engines/history.js @@ -20,6 +20,7 @@ * * Contributor(s): * Dan Mills + * Philipp von Weitershausen * Richard Newman * * Alternatively, the contents of this file may be used under the terms of @@ -36,7 +37,7 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['HistoryEngine']; +const EXPORTED_SYMBOLS = ['HistoryEngine', 'HistoryRec']; const Cc = Components.classes; const Ci = Components.interfaces; @@ -44,16 +45,27 @@ const Cu = Components.utils; const Cr = Components.results; const GUID_ANNO = "sync/guid"; +const HISTORY_TTL = 5184000; // 60 days Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/history.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/log4moz.js"); +function HistoryRec(collection, id) { + CryptoWrapper.call(this, collection, id); +} +HistoryRec.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.History", + ttl: HISTORY_TTL +}; + +Utils.deferGetSet(HistoryRec, "cleartext", ["histUri", "title", "visits"]); + + function HistoryEngine() { SyncEngine.call(this, "History"); this.downloadLimit = MAX_HISTORY_DOWNLOAD; diff --git a/services/sync/modules/engines/passwords.js b/services/sync/modules/engines/passwords.js index 2762163a9ce..f5eec3d7ee2 100644 --- a/services/sync/modules/engines/passwords.js +++ b/services/sync/modules/engines/passwords.js @@ -20,6 +20,7 @@ * Contributor(s): * Justin Dolske * Anant Narayanan + * Philipp von Weitershausen * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -35,20 +36,29 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['PasswordEngine']; +const EXPORTED_SYMBOLS = ['PasswordEngine', 'LoginRec']; const Cu = Components.utils; const Cc = Components.classes; const Ci = Components.interfaces; -Cu.import("resource://services-sync/base_records/collection.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/passwords.js"); Cu.import("resource://services-sync/util.js"); +function LoginRec(collection, id) { + CryptoWrapper.call(this, collection, id); +} +LoginRec.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.Login", +}; + +Utils.deferGetSet(LoginRec, "cleartext", ["hostname", "formSubmitURL", + "httpRealm", "username", "password", "usernameField", "passwordField"]); + + function PasswordEngine() { SyncEngine.call(this, "Passwords"); } diff --git a/services/sync/modules/engines/prefs.js b/services/sync/modules/engines/prefs.js index 77c54f24e99..4a704765461 100644 --- a/services/sync/modules/engines/prefs.js +++ b/services/sync/modules/engines/prefs.js @@ -35,7 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['PrefsEngine']; +const EXPORTED_SYMBOLS = ['PrefsEngine', 'PrefRec']; const Cc = Components.classes; const Ci = Components.interfaces; @@ -44,14 +44,23 @@ const Cu = Components.utils; const WEAVE_SYNC_PREFS = "services.sync.prefs.sync."; Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/prefs.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/ext/Preferences.js"); const PREFS_GUID = Utils.encodeBase64url(Svc.AppInfo.ID); +function PrefRec(collection, id) { + CryptoWrapper.call(this, collection, id); +} +PrefRec.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.Pref", +}; + +Utils.deferGetSet(PrefRec, "cleartext", ["value"]); + + function PrefsEngine() { SyncEngine.call(this, "Prefs"); } diff --git a/services/sync/modules/engines/tabs.js b/services/sync/modules/engines/tabs.js index 2f63da39f62..be3d3f684fd 100644 --- a/services/sync/modules/engines/tabs.js +++ b/services/sync/modules/engines/tabs.js @@ -36,18 +36,18 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ['TabEngine']; +const EXPORTED_SYMBOLS = ['TabEngine', 'TabSetRecord']; const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; +const TABS_TTL = 604800; // 7 days + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines/clients.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); -Cu.import("resource://services-sync/type_records/tabs.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/ext/Preferences.js"); @@ -58,6 +58,19 @@ Cu.import("resource://services-sync/ext/Preferences.js"); // "autoStarted" flag of nsIPrivateBrowsingService will be wrong. const PBPrefs = new Preferences("browser.privatebrowsing."); + +function TabSetRecord(collection, id) { + CryptoWrapper.call(this, collection, id); +} +TabSetRecord.prototype = { + __proto__: CryptoWrapper.prototype, + _logName: "Record.Tabs", + ttl: TABS_TTL +}; + +Utils.deferGetSet(TabSetRecord, "cleartext", ["clientName", "tabs"]); + + function TabEngine() { SyncEngine.call(this, "Tabs"); diff --git a/services/sync/modules/jpakeclient.js b/services/sync/modules/jpakeclient.js index 382c68c7f25..eee76b4db21 100644 --- a/services/sync/modules/jpakeclient.js +++ b/services/sync/modules/jpakeclient.js @@ -41,7 +41,6 @@ const Cr = Components.results; const Cu = Components.utils; Cu.import("resource://services-sync/log4moz.js"); -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/modules/main.js b/services/sync/modules/main.js index 52c619f0948..527156c56c5 100644 --- a/services/sync/modules/main.js +++ b/services/sync/modules/main.js @@ -40,11 +40,8 @@ const EXPORTED_SYMBOLS = ['Weave']; let Weave = {}; Components.utils.import("resource://services-sync/constants.js", Weave); let lazies = { - "auth.js": ['Auth', 'BrokenBasicAuthenticator', - 'BasicAuthenticator', 'NoOpAuthenticator'], - "base_records/crypto.js": - ["CollectionKeys", "BulkKeyBundle", "SyncKeyBundle"], - "engines.js": ['Engines', 'Engine', 'SyncEngine'], + "record.js": ["CollectionKeys", "BulkKeyBundle", "SyncKeyBundle"], + "engines.js": ['Engines', 'Engine', 'SyncEngine', 'Store'], "engines/bookmarks.js": ['BookmarksEngine', 'BookmarksSharingManager'], "engines/clients.js": ["Clients"], "engines/forms.js": ["FormEngine"], @@ -55,10 +52,10 @@ let lazies = { "identity.js": ["Identity", "ID"], "jpakeclient.js": ["JPAKEClient"], "notifications.js": ["Notifications", "Notification", "NotificationButton"], - "resource.js": ["Resource"], + "resource.js": ["Resource", "AsyncResource", "Auth", + "BasicAuthenticator", "NoOpAuthenticator"], "service.js": ["Service"], "status.js": ["Status"], - "stores.js": ["Store"], "util.js": ['Utils', 'Svc', 'Str'] }; diff --git a/services/sync/modules/base_records/crypto.js b/services/sync/modules/record.js similarity index 72% rename from services/sync/modules/base_records/crypto.js rename to services/sync/modules/record.js index c051de541cc..d543275a3f4 100644 --- a/services/sync/modules/base_records/crypto.js +++ b/services/sync/modules/record.js @@ -13,12 +13,14 @@ * * The Original Code is Weave. * - * The Initial Developer of the Original Code is Mozilla. + * The Initial Developer of the Original Code is + * the Mozilla Foundation. * Portions created by the Initial Developer are Copyright (C) 2008 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Dan Mills + * Philipp von Weitershausen * Richard Newman * * Alternatively, the contents of this file may be used under the terms of @@ -35,7 +37,9 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ["CryptoWrapper", "CollectionKeys", "BulkKeyBundle", "SyncKeyBundle"]; +const EXPORTED_SYMBOLS = ["WBORecord", "RecordManager", "Records", + "CryptoWrapper", "CollectionKeys", "BulkKeyBundle", + "SyncKeyBundle", "Collection"]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -43,10 +47,137 @@ const Cr = Components.results; const Cu = Components.utils; Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); Cu.import("resource://services-sync/identity.js"); -Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/log4moz.js"); +Cu.import("resource://services-sync/resource.js"); +Cu.import("resource://services-sync/util.js"); + +function WBORecord(collection, id) { + this.data = {}; + this.payload = {}; + this.collection = collection; // Optional. + this.id = id; // Optional. +} +WBORecord.prototype = { + _logName: "Record.WBO", + + get sortindex() { + if (this.data.sortindex) + return this.data.sortindex; + return 0; + }, + + // Get thyself from your URI, then deserialize. + // Set thine 'response' field. + fetch: function fetch(uri) { + let r = new Resource(uri).get(); + if (r.success) { + this.deserialize(r); // Warning! Muffles exceptions! + } + this.response = r; + return this; + }, + + upload: function upload(uri) { + return new Resource(uri).put(this); + }, + + // Take a base URI string, with trailing slash, and return the URI of this + // WBO based on collection and ID. + uri: function(base) { + if (this.collection && this.id) + return Utils.makeURL(base + this.collection + "/" + this.id); + return null; + }, + + deserialize: function deserialize(json) { + this.data = json.constructor.toString() == String ? JSON.parse(json) : json; + + try { + // The payload is likely to be JSON, but if not, keep it as a string + this.payload = JSON.parse(this.payload); + } catch(ex) {} + }, + + toJSON: function toJSON() { + // Copy fields from data to be stringified, making sure payload is a string + let obj = {}; + for (let [key, val] in Iterator(this.data)) + obj[key] = key == "payload" ? JSON.stringify(val) : val; + if (this.ttl) + obj.ttl = this.ttl; + return obj; + }, + + toString: function WBORec_toString() "{ " + [ + "id: " + this.id, + "index: " + this.sortindex, + "modified: " + this.modified, + "ttl: " + this.ttl, + "payload: " + JSON.stringify(this.payload) + ].join("\n ") + " }", +}; + +Utils.deferGetSet(WBORecord, "data", ["id", "modified", "sortindex", "payload"]); + +Utils.lazy(this, 'Records', RecordManager); + +function RecordManager() { + this._log = Log4Moz.repository.getLogger(this._logName); + this._records = {}; +} +RecordManager.prototype = { + _recordType: WBORecord, + _logName: "RecordMgr", + + import: function RecordMgr_import(url) { + this._log.trace("Importing record: " + (url.spec ? url.spec : url)); + try { + // Clear out the last response with empty object if GET fails + this.response = {}; + this.response = new Resource(url).get(); + + // Don't parse and save the record on failure + if (!this.response.success) + return null; + + let record = new this._recordType(url); + record.deserialize(this.response); + + return this.set(url, record); + } catch(ex) { + this._log.debug("Failed to import record: " + Utils.exceptionStr(ex)); + return null; + } + }, + + get: function RecordMgr_get(url) { + // Use a url string as the key to the hash + let spec = url.spec ? url.spec : url; + if (spec in this._records) + return this._records[spec]; + return this.import(url); + }, + + set: function RecordMgr_set(url, record) { + let spec = url.spec ? url.spec : url; + return this._records[spec] = record; + }, + + contains: function RecordMgr_contains(url) { + if ((url.spec || url) in this._records) + return true; + return false; + }, + + clearCache: function recordMgr_clearCache() { + this._records = {}; + }, + + del: function RecordMgr_del(url) { + delete this._records[url]; + } +}; function CryptoWrapper(collection, id) { this.cleartext = {}; @@ -558,3 +689,117 @@ SyncKeyBundle.prototype = { this._hmacObj = Utils.makeHMACKey(hmac); } }; + + +function Collection(uri, recordObj) { + Resource.call(this, uri); + this._recordObj = recordObj; + + this._full = false; + this._ids = null; + this._limit = 0; + this._older = 0; + this._newer = 0; + this._data = []; +} +Collection.prototype = { + __proto__: Resource.prototype, + _logName: "Collection", + + _rebuildURL: function Coll__rebuildURL() { + // XXX should consider what happens if it's not a URL... + this.uri.QueryInterface(Ci.nsIURL); + + let args = []; + if (this.older) + args.push('older=' + this.older); + else if (this.newer) { + args.push('newer=' + this.newer); + } + if (this.full) + args.push('full=1'); + if (this.sort) + args.push('sort=' + this.sort); + if (this.ids != null) + args.push("ids=" + this.ids); + if (this.limit > 0 && this.limit != Infinity) + args.push("limit=" + this.limit); + + this.uri.query = (args.length > 0)? '?' + args.join('&') : ''; + }, + + // get full items + get full() { return this._full; }, + set full(value) { + this._full = value; + this._rebuildURL(); + }, + + // Apply the action to a certain set of ids + get ids() this._ids, + set ids(value) { + this._ids = value; + this._rebuildURL(); + }, + + // Limit how many records to get + get limit() this._limit, + set limit(value) { + this._limit = value; + this._rebuildURL(); + }, + + // get only items modified before some date + get older() { return this._older; }, + set older(value) { + this._older = value; + this._rebuildURL(); + }, + + // get only items modified since some date + get newer() { return this._newer; }, + set newer(value) { + this._newer = value; + this._rebuildURL(); + }, + + // get items sorted by some criteria. valid values: + // oldest (oldest first) + // newest (newest first) + // index + get sort() { return this._sort; }, + set sort(value) { + this._sort = value; + this._rebuildURL(); + }, + + pushData: function Coll_pushData(data) { + this._data.push(data); + }, + + clearRecords: function Coll_clearRecords() { + this._data = []; + }, + + set recordHandler(onRecord) { + // Save this because onProgress is called with this as the ChannelListener + let coll = this; + + // Switch to newline separated records for incremental parsing + coll.setHeader("Accept", "application/newlines"); + + this._onProgress = function() { + let newline; + while ((newline = this._data.indexOf("\n")) > 0) { + // Split the json record from the rest of the data + let json = this._data.slice(0, newline); + this._data = this._data.slice(newline + 1); + + // Deserialize a record from json and give it to the callback + let record = new coll._recordObj(); + record.deserialize(json); + onRecord(record); + } + }; + } +}; diff --git a/services/sync/modules/resource.js b/services/sync/modules/resource.js index fa95cc03142..2dfed85cfe0 100644 --- a/services/sync/modules/resource.js +++ b/services/sync/modules/resource.js @@ -36,14 +36,15 @@ * * ***** END LICENSE BLOCK ***** */ -const EXPORTED_SYMBOLS = ["Resource", "AsyncResource"]; +const EXPORTED_SYMBOLS = ["Resource", "AsyncResource", + "Auth", "BrokenBasicAuthenticator", + "BasicAuthenticator", "NoOpAuthenticator"]; const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; const Cu = Components.utils; -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/ext/Observers.js"); Cu.import("resource://services-sync/ext/Preferences.js"); @@ -51,6 +52,63 @@ Cu.import("resource://services-sync/ext/Sync.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/util.js"); +Utils.lazy(this, 'Auth', AuthMgr); + +// XXX: the authenticator api will probably need to be changed to support +// other methods (digest, oauth, etc) + +function NoOpAuthenticator() {} +NoOpAuthenticator.prototype = { + onRequest: function NoOpAuth_onRequest(headers) { + return headers; + } +}; + +// Warning: This will drop the high unicode bytes from passwords. +// Use BasicAuthenticator to send non-ASCII passwords UTF8-encoded. +function BrokenBasicAuthenticator(identity) { + this._id = identity; +} +BrokenBasicAuthenticator.prototype = { + onRequest: function BasicAuth_onRequest(headers) { + headers['Authorization'] = 'Basic ' + + btoa(this._id.username + ':' + this._id.password); + return headers; + } +}; + +function BasicAuthenticator(identity) { + this._id = identity; +} +BasicAuthenticator.prototype = { + onRequest: function onRequest(headers) { + headers['Authorization'] = 'Basic ' + + btoa(this._id.username + ':' + this._id.passwordUTF8); + return headers; + } +}; + +function AuthMgr() { + this._authenticators = {}; + this.defaultAuthenticator = new NoOpAuthenticator(); +} +AuthMgr.prototype = { + defaultAuthenticator: null, + + registerAuthenticator: function AuthMgr_register(match, authenticator) { + this._authenticators[match] = authenticator; + }, + + lookupAuthenticator: function AuthMgr_lookup(uri) { + for (let match in this._authenticators) { + if (uri.match(match)) + return this._authenticators[match]; + } + return this.defaultAuthenticator; + } +}; + + /* * AsyncResource represents a remote network resource, identified by a URI. * Create an instance like so: diff --git a/services/sync/modules/service.js b/services/sync/modules/service.js index a8ac4c8bbc5..172c6d932b5 100644 --- a/services/sync/modules/service.js +++ b/services/sync/modules/service.js @@ -55,9 +55,7 @@ const CLUSTER_BACKOFF = 5 * 60 * 1000; // 5 minutes const PBKDF2_KEY_BYTES = 16; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://services-sync/auth.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines/clients.js"); diff --git a/services/sync/modules/status.js b/services/sync/modules/status.js index a00dd7262ed..442352aa4fa 100644 --- a/services/sync/modules/status.js +++ b/services/sync/modules/status.js @@ -87,7 +87,7 @@ let Status = { Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/identity.js"); - Cu.import("resource://services-sync/base_records/crypto.js"); + Cu.import("resource://services-sync/record.js"); if (!Utils.mpLocked()) { let id = ID.get("WeaveID"); if (!id) diff --git a/services/sync/modules/stores.js b/services/sync/modules/stores.js deleted file mode 100644 index 9fa23275562..00000000000 --- a/services/sync/modules/stores.js +++ /dev/null @@ -1,104 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bookmarks Sync. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ["Store"]; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/log4moz.js"); -Cu.import("resource://services-sync/util.js"); - -/* - * Data Stores - * These can wrap, serialize items and apply commands - */ - -function Store(name) { - name = name || "Unnamed"; - this.name = name.toLowerCase(); - - this._log = Log4Moz.repository.getLogger("Store." + name); - let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); - this._log.level = Log4Moz.Level[level]; -} -Store.prototype = { - applyIncoming: function Store_applyIncoming(record) { - if (record.deleted) - this.remove(record); - else if (!this.itemExists(record.id)) - this.create(record); - else - this.update(record); - }, - - // override these in derived objects - - create: function Store_create(record) { - throw "override create in a subclass"; - }, - - remove: function Store_remove(record) { - throw "override remove in a subclass"; - }, - - update: function Store_update(record) { - throw "override update in a subclass"; - }, - - itemExists: function Store_itemExists(id) { - throw "override itemExists in a subclass"; - }, - - createRecord: function Store_createRecord(id, collection) { - throw "override createRecord in a subclass"; - }, - - changeItemID: function Store_changeItemID(oldID, newID) { - throw "override changeItemID in a subclass"; - }, - - getAllIDs: function Store_getAllIDs() { - throw "override getAllIDs in a subclass"; - }, - - wipe: function Store_wipe() { - throw "override wipe in a subclass"; - } -}; diff --git a/services/sync/modules/trackers.js b/services/sync/modules/trackers.js deleted file mode 100644 index 644248bda85..00000000000 --- a/services/sync/modules/trackers.js +++ /dev/null @@ -1,167 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bookmarks Sync. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Anant Narayanan - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['Tracker']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/ext/Observers.js"); -Cu.import("resource://services-sync/log4moz.js"); -Cu.import("resource://services-sync/util.js"); - -/* - * Trackers are associated with a single engine and deal with - * listening for changes to their particular data type. - * - * There are two things they keep track of: - * 1) A score, indicating how urgently the engine wants to sync - * 2) A list of IDs for all the changed items that need to be synced - * and updating their 'score', indicating how urgently they - * want to sync. - * - */ -function Tracker(name) { - name = name || "Unnamed"; - this.name = this.file = name.toLowerCase(); - - this._log = Log4Moz.repository.getLogger("Tracker." + name); - let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug"); - this._log.level = Log4Moz.Level[level]; - - this._score = 0; - this._ignored = []; - this.ignoreAll = false; - this.changedIDs = {}; - this.loadChangedIDs(); -} -Tracker.prototype = { - /* - * Score can be called as often as desired to decide which engines to sync - * - * Valid values for score: - * -1: Do not sync unless the user specifically requests it (almost disabled) - * 0: Nothing has changed - * 100: Please sync me ASAP! - * - * Setting it to other values should (but doesn't currently) throw an exception - */ - get score() { - return this._score; - }, - - set score(value) { - this._score = value; - Observers.notify("weave:engine:score:updated", this.name); - }, - - // Should be called by service everytime a sync has been done for an engine - resetScore: function T_resetScore() { - this._score = 0; - }, - - saveChangedIDs: function T_saveChangedIDs() { - Utils.delay(function() { - Utils.jsonSave("changes/" + this.file, this, this.changedIDs); - }, 1000, this, "_lazySave"); - }, - - loadChangedIDs: function T_loadChangedIDs() { - Utils.jsonLoad("changes/" + this.file, this, function(json) { - this.changedIDs = json; - }); - }, - - // ignore/unignore specific IDs. Useful for ignoring items that are - // being processed, or that shouldn't be synced. - // But note: not persisted to disk - - ignoreID: function T_ignoreID(id) { - this.unignoreID(id); - this._ignored.push(id); - }, - - unignoreID: function T_unignoreID(id) { - let index = this._ignored.indexOf(id); - if (index != -1) - this._ignored.splice(index, 1); - }, - - addChangedID: function addChangedID(id, when) { - if (!id) { - this._log.warn("Attempted to add undefined ID to tracker"); - return false; - } - if (this.ignoreAll || (id in this._ignored)) - return false; - - // Default to the current time in seconds if no time is provided - if (when == null) - when = Math.floor(Date.now() / 1000); - - // Add/update the entry if we have a newer time - if ((this.changedIDs[id] || -Infinity) < when) { - this._log.trace("Adding changed ID: " + [id, when]); - this.changedIDs[id] = when; - this.saveChangedIDs(); - } - return true; - }, - - removeChangedID: function T_removeChangedID(id) { - if (!id) { - this._log.warn("Attempted to remove undefined ID to tracker"); - return false; - } - if (this.ignoreAll || (id in this._ignored)) - return false; - if (this.changedIDs[id] != null) { - this._log.trace("Removing changed ID " + id); - delete this.changedIDs[id]; - this.saveChangedIDs(); - } - return true; - }, - - clearChangedIDs: function T_clearChangedIDs() { - this._log.trace("Clearing changed ID list"); - this.changedIDs = {}; - this.saveChangedIDs(); - } -}; diff --git a/services/sync/modules/type_records/bookmark.js b/services/sync/modules/type_records/bookmark.js deleted file mode 100644 index c982efa30a0..00000000000 --- a/services/sync/modules/type_records/bookmark.js +++ /dev/null @@ -1,151 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ["PlacesItem", "Bookmark", "BookmarkFolder", - "BookmarkMicsum", "BookmarkQuery", "Livemark", "BookmarkSeparator"]; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -function PlacesItem(collection, id, type) { - CryptoWrapper.call(this, collection, id); - this.type = type || "item"; -} -PlacesItem.prototype = { - decrypt: function PlacesItem_decrypt() { - // Do the normal CryptoWrapper decrypt, but change types before returning - let clear = CryptoWrapper.prototype.decrypt.apply(this, arguments); - - // Convert the abstract places item to the actual object type - if (!this.deleted) - this.__proto__ = this.getTypeObject(this.type).prototype; - - return clear; - }, - - getTypeObject: function PlacesItem_getTypeObject(type) { - switch (type) { - case "bookmark": - return Bookmark; - case "microsummary": - return BookmarkMicsum; - case "query": - return BookmarkQuery; - case "folder": - return BookmarkFolder; - case "livemark": - return Livemark; - case "separator": - return BookmarkSeparator; - case "item": - return PlacesItem; - } - throw "Unknown places item object type: " + type; - }, - - __proto__: CryptoWrapper.prototype, - _logName: "Record.PlacesItem", -}; - -Utils.deferGetSet(PlacesItem, "cleartext", ["hasDupe", "parentid", "parentName", - "type"]); - -function Bookmark(collection, id, type) { - PlacesItem.call(this, collection, id, type || "bookmark"); -} -Bookmark.prototype = { - __proto__: PlacesItem.prototype, - _logName: "Record.Bookmark", -}; - -Utils.deferGetSet(Bookmark, "cleartext", ["title", "bmkUri", "description", - "loadInSidebar", "tags", "keyword"]); - -function BookmarkMicsum(collection, id) { - Bookmark.call(this, collection, id, "microsummary"); -} -BookmarkMicsum.prototype = { - __proto__: Bookmark.prototype, - _logName: "Record.BookmarkMicsum", -}; - -Utils.deferGetSet(BookmarkMicsum, "cleartext", ["generatorUri", "staticTitle"]); - -function BookmarkQuery(collection, id) { - Bookmark.call(this, collection, id, "query"); -} -BookmarkQuery.prototype = { - __proto__: Bookmark.prototype, - _logName: "Record.BookmarkQuery", -}; - -Utils.deferGetSet(BookmarkQuery, "cleartext", ["folderName"]); - -function BookmarkFolder(collection, id, type) { - PlacesItem.call(this, collection, id, type || "folder"); -} -BookmarkFolder.prototype = { - __proto__: PlacesItem.prototype, - _logName: "Record.Folder", -}; - -Utils.deferGetSet(BookmarkFolder, "cleartext", ["description", "title", - "children"]); - -function Livemark(collection, id) { - BookmarkFolder.call(this, collection, id, "livemark"); -} -Livemark.prototype = { - __proto__: BookmarkFolder.prototype, - _logName: "Record.Livemark", -}; - -Utils.deferGetSet(Livemark, "cleartext", ["siteUri", "feedUri"]); - -function BookmarkSeparator(collection, id) { - PlacesItem.call(this, collection, id, "separator"); -} -BookmarkSeparator.prototype = { - __proto__: PlacesItem.prototype, - _logName: "Record.Separator", -}; - -Utils.deferGetSet(BookmarkSeparator, "cleartext", "pos"); diff --git a/services/sync/modules/type_records/clients.js b/services/sync/modules/type_records/clients.js deleted file mode 100644 index f1e43ef8007..00000000000 --- a/services/sync/modules/type_records/clients.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ["ClientsRec"]; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -const CLIENTS_TTL = 1814400; // 21 days - -function ClientsRec(collection, id) { - CryptoWrapper.call(this, collection, id); -} -ClientsRec.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.Clients", - ttl: CLIENTS_TTL -}; - -Utils.deferGetSet(ClientsRec, "cleartext", ["name", "type", "commands"]); diff --git a/services/sync/modules/type_records/forms.js b/services/sync/modules/type_records/forms.js deleted file mode 100644 index 9319937601c..00000000000 --- a/services/sync/modules/type_records/forms.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Anant Narayanan - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['FormRec']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -const FORMS_TTL = 5184000; // 60 days - -function FormRec(collection, id) { - CryptoWrapper.call(this, collection, id); -} -FormRec.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.Form", - ttl: FORMS_TTL -}; - -Utils.deferGetSet(FormRec, "cleartext", ["name", "value"]); diff --git a/services/sync/modules/type_records/history.js b/services/sync/modules/type_records/history.js deleted file mode 100644 index 19a8d93aa9a..00000000000 --- a/services/sync/modules/type_records/history.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dan Mills - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['HistoryRec']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -const HISTORY_TTL = 5184000; // 60 days - -function HistoryRec(collection, id) { - CryptoWrapper.call(this, collection, id); -} -HistoryRec.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.History", - ttl: HISTORY_TTL -}; - -Utils.deferGetSet(HistoryRec, "cleartext", ["histUri", "title", "visits"]); diff --git a/services/sync/modules/type_records/passwords.js b/services/sync/modules/type_records/passwords.js deleted file mode 100644 index 4613b1b9222..00000000000 --- a/services/sync/modules/type_records/passwords.js +++ /dev/null @@ -1,56 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Anant Narayanan - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['LoginRec']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -function LoginRec(collection, id) { - CryptoWrapper.call(this, collection, id); -} -LoginRec.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.Login", -}; - -Utils.deferGetSet(LoginRec, "cleartext", ["hostname", "formSubmitURL", - "httpRealm", "username", "password", "usernameField", "passwordField"]); diff --git a/services/sync/modules/type_records/prefs.js b/services/sync/modules/type_records/prefs.js deleted file mode 100644 index bda358161f1..00000000000 --- a/services/sync/modules/type_records/prefs.js +++ /dev/null @@ -1,55 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Anant Narayanan - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['PrefRec']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -function PrefRec(collection, id) { - CryptoWrapper.call(this, collection, id); -} -PrefRec.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.Pref", -}; - -Utils.deferGetSet(PrefRec, "cleartext", ["value"]); diff --git a/services/sync/modules/type_records/tabs.js b/services/sync/modules/type_records/tabs.js deleted file mode 100644 index f35b171dfde..00000000000 --- a/services/sync/modules/type_records/tabs.js +++ /dev/null @@ -1,58 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Weave. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jono DiCarlo - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ['TabSetRecord']; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/util.js"); - -const TABS_TTL = 604800; // 7 days - -function TabSetRecord(collection, id) { - CryptoWrapper.call(this, collection, id); -} -TabSetRecord.prototype = { - __proto__: CryptoWrapper.prototype, - _logName: "Record.Tabs", - ttl: TABS_TTL -}; - -Utils.deferGetSet(TabSetRecord, "cleartext", ["clientName", "tabs"]); diff --git a/services/sync/tests/unit/test_auth_manager.js b/services/sync/tests/unit/test_auth_manager.js index 933a52f3145..f31772fe8d5 100644 --- a/services/sync/tests/unit/test_auth_manager.js +++ b/services/sync/tests/unit/test_auth_manager.js @@ -1,4 +1,3 @@ -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/resource.js"); diff --git a/services/sync/tests/unit/test_bookmark_engine.js b/services/sync/tests/unit/test_bookmark_engine.js index 36eb7b38276..1c1b9d9cdab 100644 --- a/services/sync/tests/unit/test_bookmark_engine.js +++ b/services/sync/tests/unit/test_bookmark_engine.js @@ -1,7 +1,5 @@ Cu.import("resource://services-sync/engines/bookmarks.js"); -Cu.import("resource://services-sync/type_records/bookmark.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_bookmark_order.js b/services/sync/tests/unit/test_bookmark_order.js index da4365d55b7..07f9593f1c9 100644 --- a/services/sync/tests/unit/test_bookmark_order.js +++ b/services/sync/tests/unit/test_bookmark_order.js @@ -1,6 +1,5 @@ _("Making sure after processing incoming bookmarks, they show up in the right order"); Cu.import("resource://services-sync/engines/bookmarks.js"); -Cu.import("resource://services-sync/type_records/bookmark.js"); Cu.import("resource://services-sync/util.js"); function getBookmarks(folderId) { diff --git a/services/sync/tests/unit/test_bookmark_record.js b/services/sync/tests/unit/test_bookmark_record.js index 1de571be7aa..8571d469b30 100644 --- a/services/sync/tests/unit/test_bookmark_record.js +++ b/services/sync/tests/unit/test_bookmark_record.js @@ -1,6 +1,5 @@ -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/type_records/bookmark.js"); -Cu.import("resource://services-sync/auth.js"); +Cu.import("resource://services-sync/record.js"); +Cu.import("resource://services-sync/engines/bookmarks.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_bookmark_store.js b/services/sync/tests/unit/test_bookmark_store.js index 7f7a72524cd..b3384a9a0ec 100644 --- a/services/sync/tests/unit/test_bookmark_store.js +++ b/services/sync/tests/unit/test_bookmark_store.js @@ -1,6 +1,5 @@ Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines/bookmarks.js"); -Cu.import("resource://services-sync/type_records/bookmark.js"); Cu.import("resource://services-sync/util.js"); const PARENT_ANNO = "sync/parent"; diff --git a/services/sync/tests/unit/test_clients_engine.js b/services/sync/tests/unit/test_clients_engine.js index 6cbbf693aa4..ce1a283f63d 100644 --- a/services/sync/tests/unit/test_clients_engine.js +++ b/services/sync/tests/unit/test_clients_engine.js @@ -1,6 +1,5 @@ Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/engines/clients.js"); diff --git a/services/sync/tests/unit/test_clients_escape.js b/services/sync/tests/unit/test_clients_escape.js index a6bd544fc9d..d52d3e1007e 100644 --- a/services/sync/tests/unit/test_clients_escape.js +++ b/services/sync/tests/unit/test_clients_escape.js @@ -1,4 +1,4 @@ -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/engines/clients.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_collection_inc_get.js b/services/sync/tests/unit/test_collection_inc_get.js index 79b94259a5d..280faa92ee2 100644 --- a/services/sync/tests/unit/test_collection_inc_get.js +++ b/services/sync/tests/unit/test_collection_inc_get.js @@ -1,6 +1,5 @@ _("Make sure Collection can correctly incrementally parse GET requests"); -Cu.import("resource://services-sync/base_records/collection.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); function run_test() { let base = "http://fake/"; diff --git a/services/sync/tests/unit/test_corrupt_keys.js b/services/sync/tests/unit/test_corrupt_keys.js index 86570f6113c..225fbabd727 100644 --- a/services/sync/tests/unit/test_corrupt_keys.js +++ b/services/sync/tests/unit/test_corrupt_keys.js @@ -4,8 +4,7 @@ Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/status.js"); Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); // For Records. -Cu.import("resource://services-sync/base_records/crypto.js"); // For CollectionKeys. +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/engines/tabs.js"); Cu.import("resource://services-sync/engines/history.js"); Cu.import("resource://services-sync/log4moz.js"); diff --git a/services/sync/tests/unit/test_engine.js b/services/sync/tests/unit/test_engine.js index 35c4e6197b0..1fb3003c354 100644 --- a/services/sync/tests/unit/test_engine.js +++ b/services/sync/tests/unit/test_engine.js @@ -1,7 +1,5 @@ Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/ext/Observers.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_forms_store.js b/services/sync/tests/unit/test_forms_store.js index 39b1ad37951..45447bc771b 100644 --- a/services/sync/tests/unit/test_forms_store.js +++ b/services/sync/tests/unit/test_forms_store.js @@ -1,6 +1,5 @@ _("Make sure the form store follows the Store api and correctly accesses the backend form storage"); Cu.import("resource://services-sync/engines/forms.js"); -Cu.import("resource://services-sync/type_records/forms.js"); function run_test() { let baseuri = "http://fake/uri/"; diff --git a/services/sync/tests/unit/test_history_engine.js b/services/sync/tests/unit/test_history_engine.js index c50497b8ad6..e1a8ae4890d 100644 --- a/services/sync/tests/unit/test_history_engine.js +++ b/services/sync/tests/unit/test_history_engine.js @@ -1,7 +1,5 @@ -Cu.import("resource://services-sync/base_records/wbo.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/engines/history.js"); -Cu.import("resource://services-sync/type_records/history.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/identity.js"); diff --git a/services/sync/tests/unit/test_history_store.js b/services/sync/tests/unit/test_history_store.js index 77e8bdcfa92..b5d6a072bf0 100644 --- a/services/sync/tests/unit/test_history_store.js +++ b/services/sync/tests/unit/test_history_store.js @@ -1,6 +1,5 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/engines/history.js"); -Cu.import("resource://services-sync/type_records/history.js"); Cu.import("resource://services-sync/util.js"); const TIMESTAMP1 = (Date.now() - 103406528) * 1000; diff --git a/services/sync/tests/unit/test_jpakeclient.js b/services/sync/tests/unit/test_jpakeclient.js index a64050f9171..8e5c9498ecd 100644 --- a/services/sync/tests/unit/test_jpakeclient.js +++ b/services/sync/tests/unit/test_jpakeclient.js @@ -1,7 +1,7 @@ Cu.import("resource://services-sync/log4moz.js"); +Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/jpakeclient.js"); Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/util.js"); const JPAKE_LENGTH_SECRET = 8; diff --git a/services/sync/tests/unit/test_keys.js b/services/sync/tests/unit/test_keys.js index 3d686cb2f2f..e28de9b42d3 100644 --- a/services/sync/tests/unit/test_keys.js +++ b/services/sync/tests/unit/test_keys.js @@ -1,6 +1,6 @@ var btoa; -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/constants.js"); btoa = Cu.import("resource://services-sync/util.js").btoa; diff --git a/services/sync/tests/unit/test_load_modules.js b/services/sync/tests/unit/test_load_modules.js index c27b5a36ca4..f426affaae0 100644 --- a/services/sync/tests/unit/test_load_modules.js +++ b/services/sync/tests/unit/test_load_modules.js @@ -1,8 +1,4 @@ const modules = [ - "auth.js", - "base_records/collection.js", - "base_records/crypto.js", - "base_records/wbo.js", "constants.js", "engines/bookmarks.js", "engines/clients.js", @@ -18,17 +14,9 @@ const modules = [ "log4moz.js", "main.js", "notifications.js", + "record.js", "resource.js", "service.js", - "stores.js", - "trackers.js", - "type_records/bookmark.js", - "type_records/clients.js", - "type_records/forms.js", - "type_records/history.js", - "type_records/passwords.js", - "type_records/prefs.js", - "type_records/tabs.js", "util.js", ]; diff --git a/services/sync/tests/unit/test_prefs_store.js b/services/sync/tests/unit/test_prefs_store.js index e9af2bdb4a0..6764310057f 100644 --- a/services/sync/tests/unit/test_prefs_store.js +++ b/services/sync/tests/unit/test_prefs_store.js @@ -1,5 +1,4 @@ Cu.import("resource://services-sync/engines/prefs.js"); -Cu.import("resource://services-sync/type_records/prefs.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/ext/Preferences.js"); diff --git a/services/sync/tests/unit/test_records_crypto.js b/services/sync/tests/unit/test_records_crypto.js index 58a8497822c..9dc308ed535 100644 --- a/services/sync/tests/unit/test_records_crypto.js +++ b/services/sync/tests/unit/test_records_crypto.js @@ -1,6 +1,6 @@ Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/auth.js"); +Cu.import("resource://services-sync/record.js"); +Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_records_crypto_generateEntry.js b/services/sync/tests/unit/test_records_crypto_generateEntry.js index 7eb317356ca..1200eb01451 100644 --- a/services/sync/tests/unit/test_records_crypto_generateEntry.js +++ b/services/sync/tests/unit/test_records_crypto_generateEntry.js @@ -1,6 +1,6 @@ let atob = Cu.import("resource://services-sync/util.js").atob; Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); /** * Testing the SHA256-HMAC key derivation process against test vectors diff --git a/services/sync/tests/unit/test_records_wbo.js b/services/sync/tests/unit/test_records_wbo.js index 950c4387666..70544c5f91f 100644 --- a/services/sync/tests/unit/test_records_wbo.js +++ b/services/sync/tests/unit/test_records_wbo.js @@ -1,6 +1,4 @@ -Cu.import("resource://services-sync/auth.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); -Cu.import("resource://services-sync/base_records/collection.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_resource.js b/services/sync/tests/unit/test_resource.js index d3ccacd0613..a666c43ebda 100644 --- a/services/sync/tests/unit/test_resource.js +++ b/services/sync/tests/unit/test_resource.js @@ -1,4 +1,3 @@ -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/ext/Observers.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/log4moz.js"); diff --git a/services/sync/tests/unit/test_resource_async.js b/services/sync/tests/unit/test_resource_async.js index 5099a54f115..7f8815ba7dd 100644 --- a/services/sync/tests/unit/test_resource_async.js +++ b/services/sync/tests/unit/test_resource_async.js @@ -1,4 +1,3 @@ -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/ext/Observers.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/log4moz.js"); diff --git a/services/sync/tests/unit/test_service_detect_upgrade.js b/services/sync/tests/unit/test_service_detect_upgrade.js index 11212a718ee..e6f3bce8a7a 100644 --- a/services/sync/tests/unit/test_service_detect_upgrade.js +++ b/services/sync/tests/unit/test_service_detect_upgrade.js @@ -4,8 +4,7 @@ Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/status.js"); Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); // For Records. -Cu.import("resource://services-sync/base_records/crypto.js"); // For CollectionKeys. +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/engines/tabs.js"); Cu.import("resource://services-sync/log4moz.js"); diff --git a/services/sync/tests/unit/test_service_passwordUTF8.js b/services/sync/tests/unit/test_service_passwordUTF8.js index a013584d3a5..e045447665b 100644 --- a/services/sync/tests/unit/test_service_passwordUTF8.js +++ b/services/sync/tests/unit/test_service_passwordUTF8.js @@ -1,4 +1,3 @@ -Cu.import("resource://services-sync/auth.js"); Cu.import("resource://services-sync/resource.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/service.js"); diff --git a/services/sync/tests/unit/test_service_sync_checkServerError.js b/services/sync/tests/unit/test_service_sync_checkServerError.js index b3046c5c2d5..a40d6ac79a3 100644 --- a/services/sync/tests/unit/test_service_sync_checkServerError.js +++ b/services/sync/tests/unit/test_service_sync_checkServerError.js @@ -5,7 +5,7 @@ Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/util.js"); Svc.DefaultPrefs.set("registerEngines", ""); Cu.import("resource://services-sync/service.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); initTestLogging(); diff --git a/services/sync/tests/unit/test_service_sync_locked.js b/services/sync/tests/unit/test_service_sync_locked.js new file mode 100644 index 00000000000..005079f1bd1 --- /dev/null +++ b/services/sync/tests/unit/test_service_sync_locked.js @@ -0,0 +1,32 @@ +Cu.import("resource://services-sync/main.js"); + +function run_test() { + let debug = []; + let info = []; + + function augmentLogger(old) { + let d = old.debug; + let i = old.info; + old.debug = function(m) { debug.push(m); d.call(old, m); } + old.info = function(m) { info.push(m); i.call(old, m); } + return old; + } + + Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender()); + + augmentLogger(Weave.Service._log); + + // Avoid daily ping + Weave.Svc.Prefs.set("lastPing", Math.floor(Date.now() / 1000)); + + _("Check that sync will log appropriately if already in 'progress'."); + Weave.Service._locked = true; + Weave.Service.sync(); + Weave.Service._locked = false; + + do_check_eq(debug[debug.length - 3], + "Exception: Could not acquire lock. Label: \"service.js: login\". No traceback available"); + do_check_eq(info[info.length - 1], + "Cannot start sync: already syncing?"); +} + diff --git a/services/sync/tests/unit/test_service_sync_remoteSetup.js b/services/sync/tests/unit/test_service_sync_remoteSetup.js index 41d6a0775c2..5e3b013b0d8 100644 --- a/services/sync/tests/unit/test_service_sync_remoteSetup.js +++ b/services/sync/tests/unit/test_service_sync_remoteSetup.js @@ -2,8 +2,7 @@ Cu.import("resource://services-sync/main.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/status.js"); Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); // For Records. -Cu.import("resource://services-sync/base_records/crypto.js"); // For CollectionKeys. +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/log4moz.js"); function run_test() { diff --git a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js index 384fd5cc7be..a3557739364 100644 --- a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js +++ b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js @@ -1,10 +1,8 @@ -Cu.import("resource://services-sync/stores.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines/clients.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); Svc.DefaultPrefs.set("registerEngines", ""); Cu.import("resource://services-sync/service.js"); diff --git a/services/sync/tests/unit/test_service_wipeClient.js b/services/sync/tests/unit/test_service_wipeClient.js index 264a41db8e0..b7674345de8 100644 --- a/services/sync/tests/unit/test_service_wipeClient.js +++ b/services/sync/tests/unit/test_service_wipeClient.js @@ -1,4 +1,4 @@ -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/util.js"); diff --git a/services/sync/tests/unit/test_service_wipeServer.js b/services/sync/tests/unit/test_service_wipeServer.js index 86ae6520fcf..f5023e85258 100644 --- a/services/sync/tests/unit/test_service_wipeServer.js +++ b/services/sync/tests/unit/test_service_wipeServer.js @@ -1,5 +1,5 @@ Cu.import("resource://services-sync/util.js"); -Cu.import("resource://services-sync/base_records/crypto.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/resource.js"); Svc.DefaultPrefs.set("registerEngines", ""); diff --git a/services/sync/tests/unit/test_syncengine_sync.js b/services/sync/tests/unit/test_syncengine_sync.js index 41e06125cdb..2ae8527a8e7 100644 --- a/services/sync/tests/unit/test_syncengine_sync.js +++ b/services/sync/tests/unit/test_syncengine_sync.js @@ -1,11 +1,8 @@ -Cu.import("resource://services-sync/base_records/crypto.js"); -Cu.import("resource://services-sync/base_records/wbo.js"); +Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/identity.js"); Cu.import("resource://services-sync/resource.js"); -Cu.import("resource://services-sync/stores.js"); -Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/util.js"); /* diff --git a/services/sync/tests/unit/test_tab_store.js b/services/sync/tests/unit/test_tab_store.js index f4a54c032d8..f5fcd961061 100644 --- a/services/sync/tests/unit/test_tab_store.js +++ b/services/sync/tests/unit/test_tab_store.js @@ -1,6 +1,5 @@ Cu.import("resource://services-sync/engines/tabs.js"); Cu.import("resource://services-sync/util.js"); -Cu.import("resource://services-sync/type_records/tabs.js"); function test_create() { let store = new TabEngine()._store; diff --git a/services/sync/tests/unit/test_tracker_addChanged.js b/services/sync/tests/unit/test_tracker_addChanged.js index 114712150e2..2e20ecf0561 100644 --- a/services/sync/tests/unit/test_tracker_addChanged.js +++ b/services/sync/tests/unit/test_tracker_addChanged.js @@ -1,4 +1,4 @@ -Cu.import("resource://services-sync/trackers.js"); +Cu.import("resource://services-sync/engines.js"); function run_test() { let tracker = new Tracker();