services/sync/Weave.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 const Cc = Components.classes;
michael@0 6 const Ci = Components.interfaces;
michael@0 7 const Cu = Components.utils;
michael@0 8
michael@0 9 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 10 Cu.import("resource://gre/modules/Services.jsm");
michael@0 11 Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 12 Cu.import("resource://gre/modules/Promise.jsm");
michael@0 13 Cu.import("resource://services-sync/util.js");
michael@0 14
michael@0 15 const SYNC_PREFS_BRANCH = "services.sync.";
michael@0 16
michael@0 17
michael@0 18 /**
michael@0 19 * Sync's XPCOM service.
michael@0 20 *
michael@0 21 * It is named "Weave" for historical reasons.
michael@0 22 *
michael@0 23 * It's worth noting how Sync is lazily loaded. We register a timer that
michael@0 24 * loads Sync a few seconds after app startup. This is so Sync does not
michael@0 25 * adversely affect application start time.
michael@0 26 *
michael@0 27 * If Sync is not configured, no extra Sync code is loaded. If an
michael@0 28 * external component (say the UI) needs to interact with Sync, it
michael@0 29 * should use the promise-base function whenLoaded() - something like the
michael@0 30 * following:
michael@0 31 *
michael@0 32 * // 1. Grab a handle to the Sync XPCOM service.
michael@0 33 * let service = Cc["@mozilla.org/weave/service;1"]
michael@0 34 * .getService(Components.interfaces.nsISupports)
michael@0 35 * .wrappedJSObject;
michael@0 36 *
michael@0 37 * // 2. Use the .then method of the promise.
michael@0 38 * service.whenLoaded().then(() => {
michael@0 39 * // You are free to interact with "Weave." objects.
michael@0 40 * return;
michael@0 41 * });
michael@0 42 *
michael@0 43 * And that's it! However, if you really want to avoid promises and do it
michael@0 44 * old-school, then
michael@0 45 *
michael@0 46 * // 1. Get a reference to the service as done in (1) above.
michael@0 47 *
michael@0 48 * // 2. Check if the service has been initialized.
michael@0 49 * if (service.ready) {
michael@0 50 * // You are free to interact with "Weave." objects.
michael@0 51 * return;
michael@0 52 * }
michael@0 53 *
michael@0 54 * // 3. Install "ready" listener.
michael@0 55 * Services.obs.addObserver(function onReady() {
michael@0 56 * Services.obs.removeObserver(onReady, "weave:service:ready");
michael@0 57 *
michael@0 58 * // You are free to interact with "Weave." objects.
michael@0 59 * }, "weave:service:ready", false);
michael@0 60 *
michael@0 61 * // 4. Trigger loading of Sync.
michael@0 62 * service.ensureLoaded();
michael@0 63 */
michael@0 64 function WeaveService() {
michael@0 65 this.wrappedJSObject = this;
michael@0 66 this.ready = false;
michael@0 67 }
michael@0 68 WeaveService.prototype = {
michael@0 69 classID: Components.ID("{74b89fb0-f200-4ae8-a3ec-dd164117f6de}"),
michael@0 70
michael@0 71 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
michael@0 72 Ci.nsISupportsWeakReference]),
michael@0 73
michael@0 74 ensureLoaded: function () {
michael@0 75 Components.utils.import("resource://services-sync/main.js");
michael@0 76
michael@0 77 // Side-effect of accessing the service is that it is instantiated.
michael@0 78 Weave.Service;
michael@0 79 },
michael@0 80
michael@0 81 whenLoaded: function() {
michael@0 82 if (this.ready) {
michael@0 83 return Promise.resolve();
michael@0 84 }
michael@0 85 let deferred = Promise.defer();
michael@0 86
michael@0 87 Services.obs.addObserver(function onReady() {
michael@0 88 Services.obs.removeObserver(onReady, "weave:service:ready");
michael@0 89 deferred.resolve();
michael@0 90 }, "weave:service:ready", false);
michael@0 91 this.ensureLoaded();
michael@0 92 return deferred.promise;
michael@0 93 },
michael@0 94
michael@0 95 /**
michael@0 96 * Whether Firefox Accounts is enabled.
michael@0 97 *
michael@0 98 * @return bool
michael@0 99 */
michael@0 100 get fxAccountsEnabled() {
michael@0 101 try {
michael@0 102 // Old sync guarantees '@' will never appear in the username while FxA
michael@0 103 // uses the FxA email address - so '@' is the flag we use.
michael@0 104 let username = Services.prefs.getCharPref(SYNC_PREFS_BRANCH + "username");
michael@0 105 return !username || username.contains('@');
michael@0 106 } catch (_) {
michael@0 107 return true; // No username == only allow FxA to be configured.
michael@0 108 }
michael@0 109 },
michael@0 110
michael@0 111 /**
michael@0 112 * Returns whether the password engine is allowed. We explicitly disallow
michael@0 113 * the password engine when a master password is used to ensure those can't
michael@0 114 * be accessed without the master key.
michael@0 115 */
michael@0 116 get allowPasswordsEngine() {
michael@0 117 // This doesn't apply to old-style sync, it's only an issue for FxA.
michael@0 118 return !this.fxAccountsEnabled || !Utils.mpEnabled();
michael@0 119 },
michael@0 120
michael@0 121 /**
michael@0 122 * Whether Sync appears to be enabled.
michael@0 123 *
michael@0 124 * This returns true if all the Sync preferences for storing account
michael@0 125 * and server configuration are populated.
michael@0 126 *
michael@0 127 * It does *not* perform a robust check to see if the client is working.
michael@0 128 * For that, you'll want to check Weave.Status.checkSetup().
michael@0 129 */
michael@0 130 get enabled() {
michael@0 131 let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
michael@0 132 return prefs.prefHasUserValue("username") &&
michael@0 133 prefs.prefHasUserValue("clusterURL");
michael@0 134 },
michael@0 135
michael@0 136 observe: function (subject, topic, data) {
michael@0 137 switch (topic) {
michael@0 138 case "app-startup":
michael@0 139 let os = Cc["@mozilla.org/observer-service;1"].
michael@0 140 getService(Ci.nsIObserverService);
michael@0 141 os.addObserver(this, "final-ui-startup", true);
michael@0 142 break;
michael@0 143
michael@0 144 case "final-ui-startup":
michael@0 145 // Force Weave service to load if it hasn't triggered from overlays
michael@0 146 this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
michael@0 147 this.timer.initWithCallback({
michael@0 148 notify: function() {
michael@0 149 // We only load more if it looks like Sync is configured.
michael@0 150 let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
michael@0 151 if (!prefs.prefHasUserValue("username")) {
michael@0 152 return;
michael@0 153 }
michael@0 154
michael@0 155 // We have a username. So, do a more thorough check. This will
michael@0 156 // import a number of modules and thus increase memory
michael@0 157 // accordingly. We could potentially copy code performed by
michael@0 158 // this check into this file if our above code is yielding too
michael@0 159 // many false positives.
michael@0 160 Components.utils.import("resource://services-sync/main.js");
michael@0 161 if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
michael@0 162 this.ensureLoaded();
michael@0 163 }
michael@0 164 }.bind(this)
michael@0 165 }, 10000, Ci.nsITimer.TYPE_ONE_SHOT);
michael@0 166 break;
michael@0 167 }
michael@0 168 }
michael@0 169 };
michael@0 170
michael@0 171 function AboutWeaveLog() {}
michael@0 172 AboutWeaveLog.prototype = {
michael@0 173 classID: Components.ID("{d28f8a0b-95da-48f4-b712-caf37097be41}"),
michael@0 174
michael@0 175 QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule,
michael@0 176 Ci.nsISupportsWeakReference]),
michael@0 177
michael@0 178 getURIFlags: function(aURI) {
michael@0 179 return 0;
michael@0 180 },
michael@0 181
michael@0 182 newChannel: function(aURI) {
michael@0 183 let dir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
michael@0 184 let uri = Services.io.newFileURI(dir);
michael@0 185 let channel = Services.io.newChannelFromURI(uri);
michael@0 186 channel.originalURI = aURI;
michael@0 187
michael@0 188 // Ensure that the about page has the same privileges as a regular directory
michael@0 189 // view. That way links to files can be opened.
michael@0 190 let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
michael@0 191 .getService(Ci.nsIScriptSecurityManager);
michael@0 192 let principal = ssm.getNoAppCodebasePrincipal(uri);
michael@0 193 channel.owner = principal;
michael@0 194 return channel;
michael@0 195 }
michael@0 196 };
michael@0 197
michael@0 198 const components = [WeaveService, AboutWeaveLog];
michael@0 199 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

mercurial