Client-side OAuth support (bug 444528, r=thunder)

This commit is contained in:
Anant Narayanan 2008-08-04 17:34:21 -07:00
Родитель b5905c72cf
Коммит f02be43079
5 изменённых файлов: 212 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,18 @@
<!ENTITY oauth.title "3rd Party Authorization">
<!ENTITY intro.title "3rd Party Authorization Wizard">
<!ENTITY intro.msg "A third party has requested access to your Weave data. Before you can authorize the party, we must first authenticate you.">
<!ENTITY intro.uid "Username:">
<!ENTITY intro.pwd "Password:">
<!ENTITY intro.pas "Verify Passphrase:">
<!ENTITY intro.loading "Please Wait...">
<!ENTITY intro.success "Your account has been verified! Please click Continue to proceed.">
<!ENTITY intro.error "Your account could not be verified, please try again!">
<!ENTITY conf.title "Authorization">
<!ENTITY conf.loading "Please wait while we verify the third party's request...">
<!ENTITY conf.proceed "By clicking the Continue button, you automatically authorize the third party. If you do not wish to grant access, you may click the Cancel button.">
<!ENTITY final.title "Granting Access to third party">
<!ENTITY final.processing "Please wait while your data is re-encrypted to enable access by the authorized third party...">
<!ENTITY final.manual "Please notify the consumer that their request token was successfully authorized!">

Просмотреть файл

@ -0,0 +1,10 @@
intro.uidmsg = You are logged in as %S
conf.conmsg = A third party identifying itself as %S is requesting access to your Weave Data.
conf.error = Sorry, but the third party's request was invalid: %S
conf.error1 = a request token was not issued.
conf.error2 = the third party is unregistered.
conf.error3 = the request token has expired.
conf.error4 = your account details could not be verified.
final.step1 = Unwrapping symmetric key...
final.step2 = Adding third party to your keyring...
final.step3 = Done!

Просмотреть файл

@ -0,0 +1,156 @@
/* ***** 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 <anant@kix.in>
*
* 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 = ['OAuth'];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://weave/log4moz.js");
Cu.import("resource://weave/constants.js");
Cu.import("resource://weave/util.js");
Cu.import("resource://weave/async.js");
Cu.import("resource://weave/identity.js");
Cu.import("resource://weave/engines.js");
Function.prototype.async = Async.sugar;
Utils.lazy(this, 'OAuth', OAuthSvc);
function OAuthSvc() {
this._init();
}
OAuthSvc.prototype = {
_logName: "OAuth",
_keyring: null,
_consKey: null,
_bulkID: null,
_rsaKey: null,
_token: null,
_cback: null,
_uid: null,
_pwd: null,
_pas: null,
_cb1: null,
_cb2: null,
_init: function OAuth__init() {
this._log = Log4Moz.Service.getLogger("Service." + this._logName);
this._log.level = "Debug";
this._log.info("OAuth Module Initialized");
},
setToken: function OAuth_setToken(token, cback) {
this._token = token;
this._cback = cback;
},
setUser: function OAuth_setUser(username, password, passphrase) {
this._uid = username;
this._pwd = password;
this._pas = passphrase;
},
validate: function OAuth_getName(obj, cb) {
if (!this._token || !this._uid || !this._pwd)
cb(obj, false);
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
var key = btoa(this._uid + ":" + this._pwd);
req.onreadystatechange = function(e) {
if (req.readyState == 4) {
if (req.status == 200) {
var fields = req.responseText.split(',');
cb(obj, fields[0], fields[1], fields[2]);
} else {
cb(obj, req.responseText);
}
}
};
req.open('GET', 'https://services.mozilla.com/api/oauth/info.php?token=' + this._token + '&key=' + key);
req.send(null);
},
finalize: function OAuth_finalize(cb1, cb2, bundle) {
this._cb1 = cb1;
this._cb2 = cb2;
this._bundle = bundle;
var bmkEngine = Engines.get('bookmarks');
var bmkRstore = bmkEngine._remote;
this._keyring = bmkRstore.keys;
this._keyring.getKeyAndIV(Utils.bind2(this, this._gotBulkKey), ID.get('WeaveID'));
},
_gotBulkKey: function OAuth_gotBulkKey() {
let consID = new Identity();
consID.pubkey = this._rsaKey;
consID.username = this._consKey;
this._cb1(this._bundle);
this._log.info("Updating keyring for 3rd party access");
this._keyring.setKey(Utils.bind2(this, this._done), ID.get('WeaveID'), consID);
},
_done: function OAuth__done() {
var cb = this._cb2;
var bu = this._bundle;
if (!this._token || !this._uid || !this._pwd)
cb(this._bundle, false);
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
var key = btoa(this._uid + ":" + this._pwd);
req.onreadystatechange = function(e) {
if (req.readyState == 4) {
if (req.status == 200 && req.responseText == "1") {
cb(bu, true);
} else {
cb(bu, false);
}
}
};
req.open('GET', 'https://services.mozilla.com/api/oauth/update.php?token=' + this._token + '&key=' + key);
req.send(null);
}
};

Просмотреть файл

@ -418,10 +418,32 @@ Keychain.prototype = {
identity.bulkKey = symkey;
identity.bulkIV = iv;
},
_setKey: function KeyChain__setKey(bulkID, newID) {
/* FIXME!: It's possible that the keyring is changed on the server
after we do a GET. Then we're just uploading this new local keyring,
thereby losing any changes made on the server keyring since this GET.
Also, if this.data was not instantiated properly (i.e. you're
using KeyChain directly instead of getting it from the engine),
you run the risk of wiping the server-side keychain.
*/
let self = yield;
this.get(self.cb);
yield;
let wrappedKey = yield Crypto.wrapKey.async(Crypto, self.cb,
bulkID.bulkKey, newID);
this.data.ring[newID.username] = wrappedKey;
this.put(self.cb, this.data);
yield;
},
getKeyAndIV: function Keychain_getKeyAndIV(onComplete, identity) {
this._getKeyAndIV.async(this, onComplete, identity);
},
setKey: function Keychain_setKey(onComplete, bulkID, newID) {
this._setKey.async(this, onComplete, bulkID, newID);
}
// FIXME: implement setKey()
};
function RemoteStore(engine) {

Просмотреть файл

@ -72,6 +72,7 @@ Cu.import("resource://weave/wrap.js");
Cu.import("resource://weave/faultTolerance.js");
Cu.import("resource://weave/crypto.js");
Cu.import("resource://weave/engines.js");
Cu.import("resource://weave/oauth.js");
Cu.import("resource://weave/dav.js");
Cu.import("resource://weave/identity.js");
Cu.import("resource://weave/async.js");
@ -99,6 +100,7 @@ Cu.import("resource://weave/dav.js", Weave);
Cu.import("resource://weave/stores.js", Weave);
Cu.import("resource://weave/syncCores.js", Weave);
Cu.import("resource://weave/engines.js", Weave);
Cu.import("resource://weave/oauth.js", Weave);
Cu.import("resource://weave/service.js", Weave);
Cu.import("resource://weave/engines/cookies.js", Weave);
Cu.import("resource://weave/engines/passwords.js", Weave);
@ -550,6 +552,9 @@ WeaveSvc.prototype = {
this._log.debug("Verifying passphrase");
this.username = username;
ID.get('WeaveID').setTempPassword(password);
let id = new Identity('Passphrase Verification', username);
id.setTempPassword(passphrase);