Bug 756366 - Preserve Sync credentials during client wipe; r=rnewman
authorGregory Szorc <gps@mozilla.com>
Tue, 22 May 2012 10:17:53 +0200
changeset 94583 efed01e37c1bdca736ac82859d685d2585fd4ba0
parent 94582 e5ee585148d5422e21ac5079b4b8c7ef6a87c488
child 94584 dac49054fb1df2bfe50c54db32d6161301961d6e
push id22732
push useremorley@mozilla.com
push dateWed, 23 May 2012 09:43:13 +0000
treeherdermozilla-central@aa2b52bd0374 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs756366
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 756366 - Preserve Sync credentials during client wipe; r=rnewman
services/sync/modules/identity.js
services/sync/modules/service.js
services/sync/tests/unit/test_service_wipeClient.js
--- a/services/sync/modules/identity.js
+++ b/services/sync/modules/identity.js
@@ -328,31 +328,31 @@ IdentityManager.prototype = {
    * Persist credentials to password store.
    *
    * When credentials are updated, they are changed in memory only. This will
    * need to be called to save them to the underlying password store.
    *
    * If the password store is locked (e.g. if the master password hasn't been
    * entered), this could throw an exception.
    */
-  persistCredentials: function persistCredentials() {
-    if (this._basicPasswordUpdated) {
+  persistCredentials: function persistCredentials(force) {
+    if (this._basicPasswordUpdated || force) {
       if (this._basicPassword) {
         this._setLogin(PWDMGR_PASSWORD_REALM, this.username,
                        this._basicPassword);
       } else {
         for each (let login in this._getLogins(PWDMGR_PASSWORD_REALM)) {
           Services.logins.removeLogin(login);
         }
       }
 
       this._basicPasswordUpdated = false;
     }
 
-    if (this._syncKeyUpdated) {
+    if (this._syncKeyUpdated || force) {
       if (this._syncKey) {
         this._setLogin(PWDMGR_PASSPHRASE_REALM, this.username, this._syncKey);
       } else {
         for each (let login in this._getLogins(PWDMGR_PASSPHRASE_REALM)) {
           Services.logins.removeLogin(login);
         }
       }
 
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -857,17 +857,17 @@ WeaveSvc.prototype = {
 
     Svc.Prefs.set("lastversion", WEAVE_VERSION);
 
     this._identity.deleteSyncCredentials();
   },
 
   persistLogin: function persistLogin() {
     try {
-      this._identity.persistCredentials();
+      this._identity.persistCredentials(true);
     } catch (ex) {
       this._log.info("Unable to persist credentials: " + ex);
     }
   },
 
   login: function login(username, password, passphrase)
     this._catch(this._lock("service.js: login",
           this._notify("login", "", function() {
--- a/services/sync/tests/unit/test_service_wipeClient.js
+++ b/services/sync/tests/unit/test_service_wipeClient.js
@@ -1,8 +1,12 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Cu.import("resource://services-sync/identity.js");
 Cu.import("resource://services-sync/record.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/util.js");
 
 Svc.DefaultPrefs.set("registerEngines", "");
 Cu.import("resource://services-sync/service.js");
 
 
@@ -39,38 +43,70 @@ CannotDecryptEngine.prototype = {
   wasWiped: false,
   wipeClient: function wipeClient() {
     this.wasWiped = true;
   }
 };
 Engines.register(CannotDecryptEngine);
 
 
-function test_withEngineList() {
+add_test(function test_withEngineList() {
   try {
     _("Ensure initial scenario.");
     do_check_false(Engines.get("candecrypt").wasWiped);
     do_check_false(Engines.get("cannotdecrypt").wasWiped);
-    
+
     _("Wipe local engine data.");
     Service.wipeClient(["candecrypt", "cannotdecrypt"]);
 
     _("Ensure only the engine that can decrypt was wiped.");
     do_check_true(Engines.get("candecrypt").wasWiped);
     do_check_false(Engines.get("cannotdecrypt").wasWiped);
   } finally {
     Engines.get("candecrypt").wasWiped = false;
     Engines.get("cannotdecrypt").wasWiped = false;
     Service.startOver();
   }
-}
 
-function test_startOver_clears_keys() {
+  run_next_test();
+});
+
+add_test(function test_startOver_clears_keys() {
   generateNewKeys();
   do_check_true(!!CollectionKeys.keyForCollection());
   Service.startOver();
   do_check_false(!!CollectionKeys.keyForCollection());
-}
+
+  run_next_test();
+});
+
+add_test(function test_credentials_preserved() {
+  _("Ensure that credentials are preserved if client is wiped.");
+
+  // Required for wipeClient().
+  Service.clusterURL = TEST_CLUSTER_URL;
+
+  Identity.account = "testaccount";
+  Identity.basicPassword = "testpassword";
+  let key = Utils.generatePassphrase();
+  Identity.syncKey = key;
+  Identity.persistCredentials();
+
+  // Simulate passwords engine wipe without all the overhead. To do this
+  // properly would require extra test infrastructure.
+  Services.logins.removeAllLogins();
+  Service.wipeClient();
+
+  let id = new IdentityManager();
+  do_check_eq(id.account, "testaccount");
+  do_check_eq(id.basicPassword, "testpassword");
+  do_check_eq(id.syncKey, key);
+
+  Service.startOver();
+
+  run_next_test();
+});
 
 function run_test() {
-  test_withEngineList();
-  test_startOver_clears_keys();
+  initTestLogging();
+
+  run_next_test();
 }