mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
support new services service (rework auth dance)
This commit is contained in:
parent
10797c184e
commit
fabe8a4f91
@ -132,6 +132,18 @@ BookmarksSyncService.prototype = {
|
|||||||
// DAVCollection object
|
// DAVCollection object
|
||||||
_dav: null,
|
_dav: null,
|
||||||
|
|
||||||
|
__encrypter: {},
|
||||||
|
__encrypterLoaded: false,
|
||||||
|
get _encrypter() {
|
||||||
|
if (!this.__encrypterLoaded) {
|
||||||
|
let jsLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||||
|
getService(Ci.mozIJSSubScriptLoader);
|
||||||
|
jsLoader.loadSubScript("chrome://sync/content/encrypt.js", this.__encrypter);
|
||||||
|
this.__encrypterLoaded = true;
|
||||||
|
}
|
||||||
|
return this.__encrypter;
|
||||||
|
},
|
||||||
|
|
||||||
// Last synced tree, version, and GUID (to detect if the store has
|
// Last synced tree, version, and GUID (to detect if the store has
|
||||||
// been completely replaced and invalidate the snapshot)
|
// been completely replaced and invalidate the snapshot)
|
||||||
_snapshot: {},
|
_snapshot: {},
|
||||||
@ -150,21 +162,74 @@ BookmarksSyncService.prototype = {
|
|||||||
this.__snapshotGUID = GUID;
|
this.__snapshotGUID = GUID;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get username() {
|
||||||
|
let branch = Cc["@mozilla.org/preferences-service;1"]
|
||||||
|
.getService(Ci.nsIPrefBranch);
|
||||||
|
return branch.getCharPref("browser.places.sync.username");
|
||||||
|
},
|
||||||
|
set username(value) {
|
||||||
|
let branch = Cc["@mozilla.org/preferences-service;1"]
|
||||||
|
.getService(Ci.nsIPrefBranch);
|
||||||
|
return branch.setCharPref("browser.places.sync.username", value);
|
||||||
|
},
|
||||||
|
|
||||||
|
get password() {
|
||||||
|
// fixme: make a request and get the realm
|
||||||
|
let password;
|
||||||
|
let lm = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
|
||||||
|
let logins = lm.findLogins({}, makeURI(this._serverURL).hostPort, null,
|
||||||
|
'services.mozilla.com - proxy');
|
||||||
|
|
||||||
|
for (let i = 0; i < logins.length; i++) {
|
||||||
|
if (logins[i].username == this.username) {
|
||||||
|
password = logins[i].password;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return password;
|
||||||
|
},
|
||||||
|
|
||||||
|
get userPath() {
|
||||||
|
this._log.info("Hashing username " + this.username);
|
||||||
|
|
||||||
|
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||||
|
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||||
|
converter.charset = "UTF-8";
|
||||||
|
|
||||||
|
let hasher = Cc["@mozilla.org/security/hash;1"]
|
||||||
|
.createInstance(Ci.nsICryptoHash);
|
||||||
|
hasher.init(hasher.SHA1);
|
||||||
|
|
||||||
|
let data = converter.convertToByteArray(this.username, {});
|
||||||
|
hasher.update(data, data.length);
|
||||||
|
let rawHash = hasher.finish(false);
|
||||||
|
|
||||||
|
// return the two-digit hexadecimal code for a byte
|
||||||
|
function toHexString(charCode) {
|
||||||
|
return ("0" + charCode.toString(16)).slice(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
let hash = [toHexString(rawHash.charCodeAt(i)) for (i in rawHash)].join("");
|
||||||
|
this._log.debug("Username hashes to " + hash);
|
||||||
|
return hash;
|
||||||
|
},
|
||||||
|
|
||||||
get currentUser() {
|
get currentUser() {
|
||||||
return this._dav.currentUser;
|
return this.username;
|
||||||
},
|
},
|
||||||
|
|
||||||
_init: function BSS__init() {
|
_init: function BSS__init() {
|
||||||
this._initLogs();
|
this._initLogs();
|
||||||
this._log.info("Bookmarks Sync Service Initializing");
|
this._log.info("Bookmarks Sync Service Initializing");
|
||||||
|
|
||||||
let serverURL = 'https://services.mozilla.com/';
|
this._serverURL = 'https://services.mozilla.com/';
|
||||||
|
this._user = '';
|
||||||
let enabled = false;
|
let enabled = false;
|
||||||
let schedule = 0;
|
let schedule = 0;
|
||||||
try {
|
try {
|
||||||
let branch = Cc["@mozilla.org/preferences-service;1"].
|
let branch = Cc["@mozilla.org/preferences-service;1"].
|
||||||
getService(Ci.nsIPrefBranch);
|
getService(Ci.nsIPrefBranch);
|
||||||
serverURL = branch.getCharPref("browser.places.sync.serverURL");
|
this._serverURL = branch.getCharPref("browser.places.sync.serverURL");
|
||||||
enabled = branch.getBoolPref("browser.places.sync.enabled");
|
enabled = branch.getBoolPref("browser.places.sync.enabled");
|
||||||
schedule = branch.getIntPref("browser.places.sync.schedule");
|
schedule = branch.getIntPref("browser.places.sync.schedule");
|
||||||
|
|
||||||
@ -172,8 +237,7 @@ BookmarksSyncService.prototype = {
|
|||||||
}
|
}
|
||||||
catch (ex) { /* use defaults */ }
|
catch (ex) { /* use defaults */ }
|
||||||
|
|
||||||
this._log.info("Bookmarks login server: " + serverURL);
|
this._dav = new DAVCollection();
|
||||||
this._dav = new DAVCollection(serverURL);
|
|
||||||
this._readSnapshot();
|
this._readSnapshot();
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
@ -1383,26 +1447,10 @@ BookmarksSyncService.prototype = {
|
|||||||
this._log.warn("generator not properly closed");
|
this._log.warn("generator not properly closed");
|
||||||
},
|
},
|
||||||
|
|
||||||
_encrypt: function BSS__encrypt(string, passphrase) {
|
|
||||||
let koFactory = Cc["@mozilla.org/security/keyobjectfactory;1"].
|
|
||||||
getService(Ci.nsIKeyObjectFactory);
|
|
||||||
let ko = koFactory.keyFromString(2, passphrase); // 2 is AES
|
|
||||||
let streamCipher = Cc["@mozilla.org/security/streamcipher;1"].
|
|
||||||
getService(Ci.nsIStreamCipher);
|
|
||||||
streamCipher.init(ko);
|
|
||||||
streamCipher.updateFromString(string);
|
|
||||||
return streamCipher.finish(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_decrypt: function BSS__decrypt(string, passphrase) {
|
|
||||||
// FIXME
|
|
||||||
},
|
|
||||||
|
|
||||||
_onLogin: function BSS__onLogin(success) {
|
_onLogin: function BSS__onLogin(success) {
|
||||||
this._loginGen.close();
|
this._loginGen.close();
|
||||||
this._loginGen = null;
|
this._loginGen = null;
|
||||||
if (success) {
|
if (success) {
|
||||||
this._log.info("Bookmarks sync server: " + this._dav.userURL);
|
|
||||||
this._os.notifyObservers(null, "bookmarks-sync:login", "");
|
this._os.notifyObservers(null, "bookmarks-sync:login", "");
|
||||||
} else {
|
} else {
|
||||||
this._os.notifyObservers(null, "bookmarks-sync:login-error", "");
|
this._os.notifyObservers(null, "bookmarks-sync:login-error", "");
|
||||||
@ -1590,10 +1638,27 @@ BookmarksSyncService.prototype = {
|
|||||||
this._log.warn("Login requested, but already logging in");
|
this._log.warn("Login requested, but already logging in");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._loggingIn = true;
|
|
||||||
this._log.info("Logging in");
|
this._log.info("Logging in");
|
||||||
|
|
||||||
|
if (!this.username) {
|
||||||
|
this._log.warn("No username set, login failed");
|
||||||
|
this._os.notifyObservers(null, "bookmarks-sync:login-error", "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.password) {
|
||||||
|
this._log.warn("No password found in password manager");
|
||||||
|
this._os.notifyObservers(null, "bookmarks-sync:login-error", "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._loggingIn = true;
|
||||||
|
|
||||||
|
this._dav.baseURL = this._serverURL + "user/" + this.userPath + "/";
|
||||||
|
this._log.info("Using server URL: " + this._dav.baseURL);
|
||||||
let callback = bind2(this, this._onLogin);
|
let callback = bind2(this, this._onLogin);
|
||||||
this._loginGen = this._dav.login.async(this._dav, callback);
|
this._loginGen = this._dav.login.async(this._dav, callback,
|
||||||
|
this.username, this.password);
|
||||||
},
|
},
|
||||||
|
|
||||||
logout: function BSS_logout() {
|
logout: function BSS_logout() {
|
||||||
@ -1677,7 +1742,7 @@ function continueGenerator(generator, data) {
|
|||||||
if (e instanceof StopIteration)
|
if (e instanceof StopIteration)
|
||||||
dump("continueGenerator warning: generator stopped unexpectedly");
|
dump("continueGenerator warning: generator stopped unexpectedly");
|
||||||
else
|
else
|
||||||
this._log.error("Exception caught: " + e.message);
|
dump("Exception caught: " + e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1735,7 +1800,6 @@ function xpath(xmlDoc, xpathString) {
|
|||||||
|
|
||||||
function DAVCollection(baseURL) {
|
function DAVCollection(baseURL) {
|
||||||
this._baseURL = baseURL;
|
this._baseURL = baseURL;
|
||||||
this._userURL = baseURL;
|
|
||||||
this._authProvider = new DummyAuthProvider();
|
this._authProvider = new DummyAuthProvider();
|
||||||
let logSvc = Cc["@mozilla.org/log4moz/service;1"].
|
let logSvc = Cc["@mozilla.org/log4moz/service;1"].
|
||||||
getService(Ci.ILog4MozService);
|
getService(Ci.ILog4MozService);
|
||||||
@ -1752,7 +1816,7 @@ DAVCollection.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
__base64: {},
|
__base64: {},
|
||||||
__vase64loaded: false,
|
__base64loaded: false,
|
||||||
get _base64() {
|
get _base64() {
|
||||||
if (!this.__base64loaded) {
|
if (!this.__base64loaded) {
|
||||||
let jsLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
let jsLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||||
@ -1763,76 +1827,23 @@ DAVCollection.prototype = {
|
|||||||
return this.__base64;
|
return this.__base64;
|
||||||
},
|
},
|
||||||
|
|
||||||
// FIXME: should we regen this each time to prevent it from staying in memory?
|
_auth: null,
|
||||||
__auth: null,
|
|
||||||
get _auth() {
|
|
||||||
if (this.__auth)
|
|
||||||
return this.__auth;
|
|
||||||
|
|
||||||
try {
|
|
||||||
this._log.debug("Generating new authentication header");
|
|
||||||
|
|
||||||
this.__authURI = this._userURL;
|
|
||||||
let URI = makeURI(this._userURL);
|
|
||||||
let username = 'nobody@mozilla.com';
|
|
||||||
let password;
|
|
||||||
|
|
||||||
let branch = Cc["@mozilla.org/preferences-service;1"].
|
|
||||||
getService(Ci.nsIPrefBranch);
|
|
||||||
username = branch.getCharPref("browser.places.sync.username");
|
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
this._log.info("No username found in password mgr, can't generate auth header");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fixme: make a request and get the realm
|
|
||||||
let lm = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
|
|
||||||
let logins = lm.findLogins({}, URI.hostPort, null,
|
|
||||||
'services.mozilla.com');
|
|
||||||
|
|
||||||
for (let i = 0; i < logins.length; i++) {
|
|
||||||
if (logins[i].username == username) {
|
|
||||||
password = logins[i].password;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!password) {
|
|
||||||
this._log.info("No password found in password mgr, can't generate auth header");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.__auth = "Basic " +
|
|
||||||
this._base64.Base64.encode(username + ":" + password);
|
|
||||||
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
return this.__auth;
|
|
||||||
},
|
|
||||||
|
|
||||||
get baseURL() {
|
get baseURL() {
|
||||||
return this._baseURL;
|
return this._baseURL;
|
||||||
},
|
},
|
||||||
|
set baseURL(value) {
|
||||||
get userURL() {
|
this._baseURL = value;
|
||||||
return this._userURL;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_loggedIn: false,
|
_loggedIn: false,
|
||||||
_currentUserPath: "nobody",
|
|
||||||
|
|
||||||
_currentUser: "nobody@mozilla.com",
|
|
||||||
get currentUser() {
|
|
||||||
return this._currentUser;
|
|
||||||
},
|
|
||||||
|
|
||||||
_makeRequest: function DC__makeRequest(onComplete, op, path, headers, data) {
|
_makeRequest: function DC__makeRequest(onComplete, op, path, headers, data) {
|
||||||
let cont = yield;
|
let cont = yield;
|
||||||
let ret;
|
let ret;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._log.debug("Creating " + op + " request for " + this._userURL + path);
|
this._log.debug("Creating " + op + " request for " + this._baseURL + path);
|
||||||
|
|
||||||
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
|
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
|
||||||
request = request.QueryInterface(Ci.nsIDOMEventTarget);
|
request = request.QueryInterface(Ci.nsIDOMEventTarget);
|
||||||
@ -1840,7 +1851,7 @@ DAVCollection.prototype = {
|
|||||||
request.addEventListener("load", new EventListener(cont, "load"), false);
|
request.addEventListener("load", new EventListener(cont, "load"), false);
|
||||||
request.addEventListener("error", new EventListener(cont, "error"), false);
|
request.addEventListener("error", new EventListener(cont, "error"), false);
|
||||||
request = request.QueryInterface(Ci.nsIXMLHttpRequest);
|
request = request.QueryInterface(Ci.nsIXMLHttpRequest);
|
||||||
request.open(op, this._userURL + path, true);
|
request.open(op, this._baseURL + path, true);
|
||||||
|
|
||||||
|
|
||||||
// Force cache validation
|
// Force cache validation
|
||||||
@ -1883,7 +1894,7 @@ DAVCollection.prototype = {
|
|||||||
return {'Authorization': this._auth? this._auth : '',
|
return {'Authorization': this._auth? this._auth : '',
|
||||||
'Content-type': 'text/plain',
|
'Content-type': 'text/plain',
|
||||||
'If': this._token?
|
'If': this._token?
|
||||||
"<" + this._userURL + "> (<" + this._token + ">)" : ''};
|
"<" + this._baseURL + "> (<" + this._token + ">)" : ''};
|
||||||
},
|
},
|
||||||
|
|
||||||
GET: function DC_GET(path, onComplete) {
|
GET: function DC_GET(path, onComplete) {
|
||||||
@ -1925,7 +1936,7 @@ DAVCollection.prototype = {
|
|||||||
|
|
||||||
// Login / Logout
|
// Login / Logout
|
||||||
|
|
||||||
login: function DC_login(onComplete) {
|
login: function DC_login(onComplete, username, password) {
|
||||||
let cont = yield;
|
let cont = yield;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1936,25 +1947,18 @@ DAVCollection.prototype = {
|
|||||||
|
|
||||||
this._log.info("Logging in");
|
this._log.info("Logging in");
|
||||||
|
|
||||||
this._userURL = this._baseURL; // for createAcct.php
|
let URI = makeURI(this._baseURL);
|
||||||
|
this._auth = "Basic " +
|
||||||
|
this._base64.Base64.encode(username + ":" + password);
|
||||||
|
|
||||||
// This ensures the auth header is correct, and it doubles as an
|
// Make a call to make sure it's working
|
||||||
// account creation request
|
let gen = this.GET("", cont);
|
||||||
let gen = this.GET("createAcct.php", cont);
|
|
||||||
let resp = yield;
|
let resp = yield;
|
||||||
gen.close();
|
gen.close();
|
||||||
|
|
||||||
if (this._authProvider._authFailed || resp.status < 200 || resp.status >= 300)
|
if (this._authProvider._authFailed || resp.status < 200 || resp.status >= 300)
|
||||||
throw 'close generator';
|
throw 'close generator';
|
||||||
|
|
||||||
let branch = Cc["@mozilla.org/preferences-service;1"].
|
|
||||||
getService(Ci.nsIPrefBranch);
|
|
||||||
this._currentUser = branch.getCharPref("browser.places.sync.username");
|
|
||||||
|
|
||||||
// FIXME: hack
|
|
||||||
let path = this._currentUser.split("@");
|
|
||||||
this._currentUserPath = path[0];
|
|
||||||
this._userURL = this._baseURL + "user/" + this._currentUserPath + "/";
|
|
||||||
this._loggedIn = true;
|
this._loggedIn = true;
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user