toolkit/identity/tests/unit/head_identity.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 const Cc = Components.classes;
michael@0 5 const Ci = Components.interfaces;
michael@0 6 const Cu = Components.utils;
michael@0 7 const Cr = Components.results;
michael@0 8
michael@0 9 Cu.import("resource://testing-common/httpd.js");
michael@0 10
michael@0 11 // XXX until bug 937114 is fixed
michael@0 12 Cu.importGlobalProperties(["atob"]);
michael@0 13
michael@0 14 // The following boilerplate makes sure that XPCom calls
michael@0 15 // that use the profile directory work.
michael@0 16
michael@0 17 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 18 Cu.import("resource://gre/modules/Services.jsm");
michael@0 19
michael@0 20 XPCOMUtils.defineLazyModuleGetter(this, "jwcrypto",
michael@0 21 "resource://gre/modules/identity/jwcrypto.jsm");
michael@0 22
michael@0 23 XPCOMUtils.defineLazyModuleGetter(this, "IDService",
michael@0 24 "resource://gre/modules/identity/Identity.jsm",
michael@0 25 "IdentityService");
michael@0 26
michael@0 27 XPCOMUtils.defineLazyModuleGetter(this,
michael@0 28 "IdentityStore",
michael@0 29 "resource://gre/modules/identity/IdentityStore.jsm");
michael@0 30
michael@0 31 XPCOMUtils.defineLazyModuleGetter(this,
michael@0 32 "Logger",
michael@0 33 "resource://gre/modules/identity/LogUtils.jsm");
michael@0 34
michael@0 35 XPCOMUtils.defineLazyServiceGetter(this,
michael@0 36 "uuidGenerator",
michael@0 37 "@mozilla.org/uuid-generator;1",
michael@0 38 "nsIUUIDGenerator");
michael@0 39
michael@0 40 const TEST_MESSAGE_MANAGER = "Mr McFeeley";
michael@0 41 const TEST_URL = "https://myfavoritebacon.com";
michael@0 42 const TEST_URL2 = "https://myfavoritebaconinacan.com";
michael@0 43 const TEST_USER = "user@mozilla.com";
michael@0 44 const TEST_PRIVKEY = "fake-privkey";
michael@0 45 const TEST_CERT = "fake-cert";
michael@0 46 const TEST_ASSERTION = "fake-assertion";
michael@0 47 const TEST_IDPPARAMS = {
michael@0 48 domain: "myfavoriteflan.com",
michael@0 49 authentication: "/foo/authenticate.html",
michael@0 50 provisioning: "/foo/provision.html"
michael@0 51 };
michael@0 52
michael@0 53 // The following are utility functions for Identity testing
michael@0 54
michael@0 55 function log(...aMessageArgs) {
michael@0 56 Logger.log.apply(Logger, ["test"].concat(aMessageArgs));
michael@0 57 }
michael@0 58
michael@0 59 function get_idstore() {
michael@0 60 return IdentityStore;
michael@0 61 }
michael@0 62
michael@0 63 function partial(fn) {
michael@0 64 let args = Array.prototype.slice.call(arguments, 1);
michael@0 65 return function() {
michael@0 66 return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
michael@0 67 };
michael@0 68 }
michael@0 69
michael@0 70 function uuid() {
michael@0 71 return uuidGenerator.generateUUID().toString();
michael@0 72 }
michael@0 73
michael@0 74 function base64UrlDecode(s) {
michael@0 75 s = s.replace(/-/g, "+");
michael@0 76 s = s.replace(/_/g, "/");
michael@0 77
michael@0 78 // Replace padding if it was stripped by the sender.
michael@0 79 // See http://tools.ietf.org/html/rfc4648#section-4
michael@0 80 switch (s.length % 4) {
michael@0 81 case 0:
michael@0 82 break; // No pad chars in this case
michael@0 83 case 2:
michael@0 84 s += "==";
michael@0 85 break; // Two pad chars
michael@0 86 case 3:
michael@0 87 s += "=";
michael@0 88 break; // One pad char
michael@0 89 default:
michael@0 90 throw new InputException("Illegal base64url string!");
michael@0 91 }
michael@0 92
michael@0 93 // With correct padding restored, apply the standard base64 decoder
michael@0 94 return atob(s);
michael@0 95 }
michael@0 96
michael@0 97 // create a mock "doc" object, which the Identity Service
michael@0 98 // uses as a pointer back into the doc object
michael@0 99 function mock_doc(aIdentity, aOrigin, aDoFunc) {
michael@0 100 let mockedDoc = {};
michael@0 101 mockedDoc.id = uuid();
michael@0 102 mockedDoc.loggedInUser = aIdentity;
michael@0 103 mockedDoc.origin = aOrigin;
michael@0 104 mockedDoc["do"] = aDoFunc;
michael@0 105 mockedDoc._mm = TEST_MESSAGE_MANAGER;
michael@0 106 mockedDoc.doReady = partial(aDoFunc, "ready");
michael@0 107 mockedDoc.doLogin = partial(aDoFunc, "login");
michael@0 108 mockedDoc.doLogout = partial(aDoFunc, "logout");
michael@0 109 mockedDoc.doError = partial(aDoFunc, "error");
michael@0 110 mockedDoc.doCancel = partial(aDoFunc, "cancel");
michael@0 111 mockedDoc.doCoffee = partial(aDoFunc, "coffee");
michael@0 112 mockedDoc.childProcessShutdown = partial(aDoFunc, "child-process-shutdown");
michael@0 113
michael@0 114 mockedDoc.RP = mockedDoc;
michael@0 115
michael@0 116 return mockedDoc;
michael@0 117 }
michael@0 118
michael@0 119 function mock_fxa_rp(aIdentity, aOrigin, aDoFunc) {
michael@0 120 let mockedDoc = {};
michael@0 121 mockedDoc.id = uuid();
michael@0 122 mockedDoc.emailHint = aIdentity;
michael@0 123 mockedDoc.origin = aOrigin;
michael@0 124 mockedDoc.wantIssuer = "firefox-accounts";
michael@0 125 mockedDoc._mm = TEST_MESSAGE_MANAGER;
michael@0 126
michael@0 127 mockedDoc.doReady = partial(aDoFunc, "ready");
michael@0 128 mockedDoc.doLogin = partial(aDoFunc, "login");
michael@0 129 mockedDoc.doLogout = partial(aDoFunc, "logout");
michael@0 130 mockedDoc.doError = partial(aDoFunc, "error");
michael@0 131 mockedDoc.doCancel = partial(aDoFunc, "cancel");
michael@0 132 mockedDoc.childProcessShutdown = partial(aDoFunc, "child-process-shutdown");
michael@0 133
michael@0 134 mockedDoc.RP = mockedDoc;
michael@0 135
michael@0 136 return mockedDoc;
michael@0 137 }
michael@0 138
michael@0 139 // mimicking callback funtionality for ease of testing
michael@0 140 // this observer auto-removes itself after the observe function
michael@0 141 // is called, so this is meant to observe only ONE event.
michael@0 142 function makeObserver(aObserveTopic, aObserveFunc) {
michael@0 143 let observer = {
michael@0 144 // nsISupports provides type management in C++
michael@0 145 // nsIObserver is to be an observer
michael@0 146 QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
michael@0 147
michael@0 148 observe: function (aSubject, aTopic, aData) {
michael@0 149 if (aTopic == aObserveTopic) {
michael@0 150 aObserveFunc(aSubject, aTopic, aData);
michael@0 151 Services.obs.removeObserver(observer, aObserveTopic);
michael@0 152 }
michael@0 153 }
michael@0 154 };
michael@0 155
michael@0 156 Services.obs.addObserver(observer, aObserveTopic, false);
michael@0 157 }
michael@0 158
michael@0 159 // set up the ID service with an identity with keypair and all
michael@0 160 // when ready, invoke callback with the identity
michael@0 161 function setup_test_identity(identity, cert, cb) {
michael@0 162 // set up the store so that we're supposed to be logged in
michael@0 163 let store = get_idstore();
michael@0 164
michael@0 165 function keyGenerated(err, kpo) {
michael@0 166 store.addIdentity(identity, kpo, cert);
michael@0 167 cb();
michael@0 168 };
michael@0 169
michael@0 170 jwcrypto.generateKeyPair("DS160", keyGenerated);
michael@0 171 }
michael@0 172
michael@0 173 // takes a list of functions and returns a function that
michael@0 174 // when called the first time, calls the first func,
michael@0 175 // then the next time the second, etc.
michael@0 176 function call_sequentially() {
michael@0 177 let numCalls = 0;
michael@0 178 let funcs = arguments;
michael@0 179
michael@0 180 return function() {
michael@0 181 if (!funcs[numCalls]) {
michael@0 182 let argString = Array.prototype.slice.call(arguments).join(",");
michael@0 183 do_throw("Too many calls: " + argString);
michael@0 184 return;
michael@0 185 }
michael@0 186 funcs[numCalls].apply(funcs[numCalls],arguments);
michael@0 187 numCalls += 1;
michael@0 188 };
michael@0 189 }
michael@0 190
michael@0 191 /*
michael@0 192 * Setup a provisioning workflow with appropriate callbacks
michael@0 193 *
michael@0 194 * identity is the email we're provisioning.
michael@0 195 *
michael@0 196 * afterSetupCallback is required.
michael@0 197 *
michael@0 198 * doneProvisioningCallback is optional, if the caller
michael@0 199 * wants to be notified when the whole provisioning workflow is done
michael@0 200 *
michael@0 201 * frameCallbacks is optional, contains the callbacks that the sandbox
michael@0 202 * frame would provide in response to DOM calls.
michael@0 203 */
michael@0 204 function setup_provisioning(identity, afterSetupCallback, doneProvisioningCallback, callerCallbacks) {
michael@0 205 IDService.reset();
michael@0 206
michael@0 207 let provId = uuid();
michael@0 208 IDService.IDP._provisionFlows[provId] = {
michael@0 209 identity : identity,
michael@0 210 idpParams: TEST_IDPPARAMS,
michael@0 211 callback: function(err) {
michael@0 212 if (doneProvisioningCallback)
michael@0 213 doneProvisioningCallback(err);
michael@0 214 },
michael@0 215 sandbox: {
michael@0 216 // Emulate the free() method on the iframe sandbox
michael@0 217 free: function() {}
michael@0 218 }
michael@0 219 };
michael@0 220
michael@0 221 let caller = {};
michael@0 222 caller.id = provId;
michael@0 223 caller.doBeginProvisioningCallback = function(id, duration_s) {
michael@0 224 if (callerCallbacks && callerCallbacks.beginProvisioningCallback)
michael@0 225 callerCallbacks.beginProvisioningCallback(id, duration_s);
michael@0 226 };
michael@0 227 caller.doGenKeyPairCallback = function(pk) {
michael@0 228 if (callerCallbacks && callerCallbacks.genKeyPairCallback)
michael@0 229 callerCallbacks.genKeyPairCallback(pk);
michael@0 230 };
michael@0 231
michael@0 232 afterSetupCallback(caller);
michael@0 233 }
michael@0 234
michael@0 235 // Switch debug messages on by default
michael@0 236 let initialPrefDebugValue = false;
michael@0 237 try {
michael@0 238 initialPrefDebugValue = Services.prefs.getBoolPref("toolkit.identity.debug");
michael@0 239 } catch(noPref) {}
michael@0 240 Services.prefs.setBoolPref("toolkit.identity.debug", true);
michael@0 241
michael@0 242 // Switch on firefox accounts
michael@0 243 let initialPrefFXAValue = false;
michael@0 244 try {
michael@0 245 initialPrefFXAValue = Services.prefs.getBoolPref("identity.fxaccounts.enabled");
michael@0 246 } catch(noPref) {}
michael@0 247 Services.prefs.setBoolPref("identity.fxaccounts.enabled", true);
michael@0 248
michael@0 249 // after execution, restore prefs
michael@0 250 do_register_cleanup(function() {
michael@0 251 log("restoring prefs to their initial values");
michael@0 252 Services.prefs.setBoolPref("toolkit.identity.debug", initialPrefDebugValue);
michael@0 253 Services.prefs.setBoolPref("identity.fxaccounts.enabled", initialPrefFXAValue);
michael@0 254 });
michael@0 255
michael@0 256

mercurial