Bug 925101 - Remove legacy signons.txt files. r?dolske draft
authorRay Lin <ralin@mozilla.com>
Tue, 19 Apr 2016 17:28:01 +0800
changeset 357723 69b30a7da7a58d4d49e8809128e8eda63992bd67
parent 357432 6adc822f5e27a55551faeb6c47a9bd8b0859a23b
child 519689 524d710347bf32f44cbca39801e82b8d03ca9a16
push id16828
push userbmo:ralin@mozilla.com
push dateFri, 29 Apr 2016 07:19:21 +0000
reviewersdolske
bugs925101
milestone49.0a1
Bug 925101 - Remove legacy signons.txt files. r?dolske MozReview-Commit-ID: ICZADhIeKiB
browser/components/nsBrowserGlue.js
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/test/unit/test_module_LoginHelper.js
toolkit/components/passwordmgr/test/unit/xpcshell.ini
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -103,16 +103,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource:///modules/BrowserUITelemetry.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
                                   "resource://gre/modules/AsyncShutdown.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
                                   "resource://gre/modules/LoginManagerParent.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
+                                  "resource://gre/modules/LoginHelper.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "SimpleServiceDiscovery",
                                   "resource://gre/modules/SimpleServiceDiscovery.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
                                   "resource:///modules/ContentSearch.jsm");
 
 if (AppConstants.E10S_TESTING_ONLY) {
   XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
@@ -1826,17 +1829,17 @@ BrowserGlue.prototype = {
     var notifyBox = win.gBrowser.getNotificationBox();
     var notification = notifyBox.appendNotification(text, title, null,
                                                     notifyBox.PRIORITY_CRITICAL_MEDIUM,
                                                     buttons);
     notification.persistence = -1; // Until user closes it
   },
 
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 37;
+    const UI_VERSION = 38;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
@@ -2192,16 +2195,19 @@ BrowserGlue.prototype = {
                            "passwordCol",
                            "hidden");
     }
 
     if (currentUIVersion < 37) {
       Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
     }
 
+    if (currentUIVersion < 38) {
+      LoginHelper.removeLegacySignonFiles();
+    }
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _hasExistingNotificationPermission: function BG__hasExistingNotificationPermission() {
     let enumerator = Services.perms.enumerator;
     while (enumerator.hasMoreElements()) {
       let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -445,10 +445,37 @@ this.LoginHelper = {
     return formLogin;
   },
 
   /**
    * As above, but for an array of objects.
    */
   vanillaObjectsToLogins(logins) {
     return logins.map(this.vanillaObjectToLogin);
+  },
+
+  removeLegacySignonFiles() {
+    const {Constants, Path, File} = Cu.import("resource://gre/modules/osfile.jsm").OS;
+
+    const profileDir = Constants.Path.profileDir;
+    const defaultSignonFilePrefs = new Map([
+      ["signon.SignonFileName", "signons.txt"],
+      ["signon.SignonFileName2", "signons2.txt"],
+      ["signon.SignonFileName3", "signons3.txt"]
+    ]);
+    const toDeletes = new Set();
+
+    for (let [pref, val] of defaultSignonFilePrefs.entries()) {
+      toDeletes.add(Path.join(profileDir, val));
+
+      try {
+        let signonFile = Services.prefs.getCharPref(pref);
+
+        toDeletes.add(Path.normalize(Path.join(profileDir, signonFile)));
+        Services.prefs.clearUserPref(pref);
+      } catch (e) {}
+    }
+
+    for (let file of toDeletes) {
+      File.remove(file);
+    }
   }
 };
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/unit/test_module_LoginHelper.js
@@ -0,0 +1,68 @@
+/**
+ * Tests the LoginHelper object.
+ */
+
+"use strict";
+
+
+Cu.import("resource://gre/modules/Task.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
+                                  "resource://gre/modules/LoginHelper.jsm");
+
+
+function* createSignonFile(singon) {
+  let {file, pref}  = singon;
+
+  if (pref) {
+    Services.prefs.setCharPref(pref, file);
+  }
+
+  yield OS.File.open(
+    OS.Path.join(OS.Constants.Path.profileDir, file), { create: true });
+}
+
+function* isSignonClear(singon) {
+  const {file, pref} = singon;
+  const fileExists = yield OS.File.exists(
+    OS.Path.join(OS.Constants.Path.profileDir, file));
+
+  if (pref) {
+    try {
+      Services.prefs.getCharPref(pref);
+      return false;
+    } catch (e) {}
+  }
+
+  return !fileExists;
+}
+
+add_task(function* test_remove_lagecy_signonfile() {
+  const signonsSettings = [[
+    { file: "signons.txt" },
+    { file: "signons2.txt" },
+    { file: "signons3.txt" }
+  ], [
+    { file: "signons.txt", pref: "signon.SignonFileName" },
+    { file: "signons2.txt", pref: "signon.SignonFileName2" },
+    { file: "signons3.txt", pref: "signon.SignonFileName3" }
+  ], [
+    { file: "signons.txt" },
+    { file: "signons2.txt" },
+    { file: "singons.txt", pref: "signon.SignonFileName" },
+    { file: "customized2.txt", pref: "signon.SignonFileName2" },
+    { file: "customized3.txt", pref: "signon.SignonFileName3" }
+  ]];
+
+  for (let setting of signonsSettings) {
+    for (let singon of setting) {
+      yield createSignonFile(singon);
+    }
+
+    LoginHelper.removeLegacySignonFiles();
+
+    for (let singon of setting) {
+      do_check_eq(yield isSignonClear(singon), true);
+    }
+  }
+});
--- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini
+++ b/toolkit/components/passwordmgr/test/unit/xpcshell.ini
@@ -3,16 +3,17 @@ head = head.js
 tail =
 skip-if = toolkit == 'gonk'
 support-files = data/**
 
 # Test JSON file access and import from SQLite, not applicable to Android.
 [test_module_LoginImport.js]
 skip-if = os == "android"
 [test_module_LoginStore.js]
+[test_module_LoginHelper.js]
 skip-if = os == "android"
 
 # Test SQLite database backup and migration, applicable to Android only.
 [test_storage_mozStorage.js]
 skip-if = true || os != "android" # Bug 1171687: Needs fixing on Android
 
 # The following tests apply to any storage back-end.
 [test_context_menu.js]