Backout 7d1b925bd4ee and 52e5b438c911 (Bug 753239) due to almost permaorange.

This commit is contained in:
Ryan VanderMeulen 2012-07-10 19:21:54 -04:00
parent 89aff4650d
commit 45165360da
21 changed files with 2 additions and 2333 deletions

View File

@ -474,9 +474,6 @@
@BINPATH@/components/Webapps.manifest
@BINPATH@/components/AppsService.js
@BINPATH@/components/AppsService.manifest
@BINPATH@/components/nsDOMIdentity.js
@BINPATH@/components/nsIDService.js
@BINPATH@/components/Identity.manifest
@BINPATH@/components/ContactManager.js
@BINPATH@/components/ContactManager.manifest

View File

@ -67,7 +67,6 @@ DIRS += \
indexedDB \
system \
ipc \
identity \
workers \
$(NULL)

View File

@ -1,266 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
// This is the parent process corresponding to nsDOMIdentity.
let EXPORTED_SYMBOLS = ["DOMIdentity"];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "IdentityService",
"resource://gre/modules/identity/Identity.jsm");
XPCOMUtils.defineLazyModuleGetter(this,
"Logger",
"resource://gre/modules/identity/LogUtils.jsm");
function log(...aMessageArgs) {
Logger.log(["DOMIdentity"].concat(aMessageArgs));
}
function IDDOMMessage(aID) {
this.id = aID;
}
function IDPProvisioningContext(aID, aOrigin, aTargetMM) {
this._id = aID;
this._origin = aOrigin;
this._mm = aTargetMM;
}
IDPProvisioningContext.prototype = {
get id() this._id,
get origin() this._origin,
doBeginProvisioningCallback: function IDPPC_doBeginProvCB(aID, aCertDuration) {
let message = new IDDOMMessage(this.id);
message.identity = aID;
message.certDuration = aCertDuration;
this._mm.sendAsyncMessage("Identity:IDP:CallBeginProvisioningCallback",
message);
},
doGenKeyPairCallback: function IDPPC_doGenKeyPairCallback(aPublicKey) {
log("doGenKeyPairCallback");
let message = new IDDOMMessage(this.id);
message.publicKey = aPublicKey;
this._mm.sendAsyncMessage("Identity:IDP:CallGenKeyPairCallback", message);
},
doError: function(msg) {
log("Provisioning ERROR: " + msg);
},
};
function IDPAuthenticationContext(aID, aOrigin, aTargetMM) {
this._id = aID;
this._origin = aOrigin;
this._mm = aTargetMM;
}
IDPAuthenticationContext.prototype = {
get id() this._id,
get origin() this._origin,
doBeginAuthenticationCallback: function IDPAC_doBeginAuthCB(aIdentity) {
let message = new IDDOMMessage(this.id);
message.identity = aIdentity;
this._mm.sendAsyncMessage("Identity:IDP:CallBeginAuthenticationCallback",
message);
},
doError: function IDPAC_doError(msg) {
log("Authentication ERROR: " + msg);
},
};
function RPWatchContext(aID, aOrigin, aLoggedInEmail, aTargetMM) {
this._id = aID;
this._origin = aOrigin;
this._loggedInEmail = aLoggedInEmail;
this._mm = aTargetMM;
}
RPWatchContext.prototype = {
get id() this._id,
get origin() this._origin,
get loggedInEmail() this._loggedInEmail,
doLogin: function RPWatchContext_onlogin(aAssertion) {
log("doLogin: " + this.id);
let message = new IDDOMMessage(this.id);
message.assertion = aAssertion;
this._mm.sendAsyncMessage("Identity:RP:Watch:OnLogin", message);
},
doLogout: function RPWatchContext_onlogout() {
log("doLogout :" + this.id);
let message = new IDDOMMessage(this.id);
this._mm.sendAsyncMessage("Identity:RP:Watch:OnLogout", message);
},
doReady: function RPWatchContext_onready() {
log("doReady: " + this.id);
let message = new IDDOMMessage(this.id);
this._mm.sendAsyncMessage("Identity:RP:Watch:OnReady", message);
},
doError: function RPWatchContext_onerror(aMessage) {
log("doError: " + aMessage);
}
};
let DOMIdentity = {
// nsIFrameMessageListener
receiveMessage: function DOMIdentity_receiveMessage(aMessage) {
let msg = aMessage.json;
// Target is the frame message manager that called us and is
// used to send replies back to the proper window.
let targetMM = aMessage.target
.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader.messageManager;
switch (aMessage.name) {
// RP
case "Identity:RP:Watch":
this._watch(msg, targetMM);
break;
case "Identity:RP:Request":
this._request(msg);
break;
case "Identity:RP:Logout":
this._logout(msg);
break;
// IDP
case "Identity:IDP:BeginProvisioning":
this._beginProvisioning(msg, targetMM);
break;
case "Identity:IDP:GenKeyPair":
this._genKeyPair(msg);
break;
case "Identity:IDP:RegisterCertificate":
this._registerCertificate(msg);
break;
case "Identity:IDP:ProvisioningFailure":
this._provisioningFailure(msg);
break;
case "Identity:IDP:BeginAuthentication":
this._beginAuthentication(msg, targetMM);
break;
case "Identity:IDP:CompleteAuthentication":
this._completeAuthentication(msg);
break;
case "Identity:IDP:AuthenticationFailure":
this._authenticationFailure(msg);
break;
}
},
// nsIObserver
observe: function DOMIdentity_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "domwindowopened":
case "domwindowclosed":
let win = aSubject.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
this._configureMessages(win, aTopic == "domwindowopened");
break;
case "xpcom-shutdown":
Services.ww.unregisterNotification(this);
Services.obs.removeObserver(this, "xpcom-shutdown");
break;
}
},
messages: ["Identity:RP:Watch", "Identity:RP:Request", "Identity:RP:Logout",
"Identity:IDP:BeginProvisioning", "Identity:IDP:ProvisioningFailure",
"Identity:IDP:RegisterCertificate", "Identity:IDP:GenKeyPair",
"Identity:IDP:BeginAuthentication",
"Identity:IDP:CompleteAuthentication",
"Identity:IDP:AuthenticationFailure"],
// Private.
_init: function DOMIdentity__init() {
Services.ww.registerNotification(this);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
_configureMessages: function DOMIdentity__configureMessages(aWindow, aRegister) {
if (!aWindow.messageManager)
return;
let func = aWindow.messageManager[aRegister ? "addMessageListener"
: "removeMessageListener"];
for (let message of this.messages) {
func(message, this);
}
},
_resetFrameState: function(aContext) {
log("_resetFrameState: ", aContext.id);
if (!aContext._mm) {
throw new Error("ERROR: Trying to reset an invalid context");
}
let message = new IDDOMMessage(aContext.id);
aContext._mm.sendAsyncMessage("Identity:ResetState", message);
},
_watch: function DOMIdentity__watch(message, targetMM) {
log("DOMIdentity__watch: " + message.id);
// Pass an object with the watch members to Identity.jsm so it can call the
// callbacks.
let context = new RPWatchContext(message.id, message.origin,
message.loggedInEmail, targetMM);
IdentityService.RP.watch(context);
},
_request: function DOMIdentity__request(message) {
IdentityService.RP.request(message.id, message);
},
_logout: function DOMIdentity__logout(message) {
IdentityService.RP.logout(message.id, message.origin);
},
_beginProvisioning: function DOMIdentity__beginProvisioning(message, targetMM) {
let context = new IDPProvisioningContext(message.id, message.origin,
targetMM);
IdentityService.IDP.beginProvisioning(context);
},
_genKeyPair: function DOMIdentity__genKeyPair(message) {
IdentityService.IDP.genKeyPair(message.id);
},
_registerCertificate: function DOMIdentity__registerCertificate(message) {
IdentityService.IDP.registerCertificate(message.id, message.cert);
},
_provisioningFailure: function DOMIdentity__provisioningFailure(message) {
IdentityService.IDP.raiseProvisioningFailure(message.id, message.reason);
},
_beginAuthentication: function DOMIdentity__beginAuthentication(message, targetMM) {
let context = new IDPAuthenticationContext(message.id, message.origin,
targetMM);
IdentityService.IDP.beginAuthentication(context);
},
_completeAuthentication: function DOMIdentity__completeAuthentication(message) {
IdentityService.IDP.completeAuthentication(message.id);
},
_authenticationFailure: function DOMIdentity__authenticationFailure(message) {
IdentityService.IDP.cancelAuthentication(message.id);
},
};
// Object is initialized by nsIDService.js

View File

@ -1,9 +0,0 @@
# nsDOMIdentity.js
component {8bcac6a3-56a4-43a4-a44c-cdf42763002f} nsDOMIdentity.js
contract @mozilla.org/dom/identity;1 {8bcac6a3-56a4-43a4-a44c-cdf42763002f}
category JavaScript-navigator-property id @mozilla.org/dom/identity;1
# nsIDService.js (initialization on startup)
component {baa581e5-8e72-406c-8c9f-dcd4b23a6f82} nsIDService.js
contract @mozilla.org/dom/identity/service;1 {baa581e5-8e72-406c-8c9f-dcd4b23a6f82}
category app-startup IDService @mozilla.org/dom/identity/service;1

View File

@ -1,28 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/identity
include $(DEPTH)/config/autoconf.mk
EXTRA_COMPONENTS = \
nsDOMIdentity.js \
nsIDService.js \
Identity.manifest \
$(NULL)
EXTRA_JS_MODULES = \
DOMIdentity.jsm \
$(NULL)
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk

View File

@ -1,530 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const PREF_DEBUG = "toolkit.identity.debug";
const PREF_ENABLED = "dom.identity.enabled";
// Maximum length of a string that will go through IPC
const MAX_STRING_LENGTH = 2048;
// Maximum number of times navigator.id.request can be called for a document
const MAX_RP_CALLS = 100;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// This is the child process corresponding to nsIDOMIdentity.
function nsDOMIdentity(aIdentityInternal) {
this._identityInternal = aIdentityInternal;
}
nsDOMIdentity.prototype = {
__exposedProps__: {
// Relying Party (RP)
watch: 'r',
request: 'r',
logout: 'r',
// Provisioning
beginProvisioning: 'r',
genKeyPair: 'r',
registerCertificate: 'r',
raiseProvisioningFailure: 'r',
// Authentication
beginAuthentication: 'r',
completeAuthentication: 'r',
raiseAuthenticationFailure: 'r',
},
// nsIDOMIdentity
/**
* Relying Party (RP) APIs
*/
watch: function nsDOMIdentity_watch(aOptions) {
this._log("watch");
if (this._rpWatcher) {
throw new Error("navigator.id.watch was already called");
}
if (!aOptions || typeof(aOptions) !== "object") {
throw new Error("options argument to watch is required");
}
// Check for required callbacks
let requiredCallbacks = ["onlogin", "onlogout"];
for (let cbName of requiredCallbacks) {
if ((!(cbName in aOptions))
|| typeof(aOptions[cbName]) !== "function") {
throw new Error(cbName + " callback is required.");
}
}
// Optional callback "onready"
if (aOptions["onready"]
&& typeof(aOptions['onready']) !== "function") {
throw new Error("onready must be a function");
}
let message = this.DOMIdentityMessage();
// loggedInEmail
message.loggedInEmail = null;
let emailType = typeof(aOptions["loggedInEmail"]);
if (aOptions["loggedInEmail"] && aOptions["loggedInEmail"] !== "undefined") {
if (emailType !== "string") {
throw new Error("loggedInEmail must be a String or null");
}
// TODO: Bug 767610 - check email format.
// See nsHTMLInputElement::IsValidEmailAddress
if (aOptions["loggedInEmail"].indexOf("@") == -1
|| aOptions["loggedInEmail"].length > MAX_STRING_LENGTH) {
throw new Error("loggedInEmail is not valid");
}
// Set loggedInEmail in this block that "undefined" doesn't get through.
message.loggedInEmail = aOptions.loggedInEmail;
}
this._log("loggedInEmail: " + message.loggedInEmail);
this._rpWatcher = aOptions;
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Watch", message);
},
request: function nsDOMIdentity_request(aOptions) {
// TODO: Bug 769569 - "must be invoked from within a click handler"
// Has the caller called watch() before this?
if (!this._rpWatcher) {
throw new Error("navigator.id.request called before navigator.id.watch");
}
if (this._rpCalls > MAX_RP_CALLS) {
throw new Error("navigator.id.request called too many times");
}
let message = this.DOMIdentityMessage();
if (aOptions) {
// Optional string properties
let optionalStringProps = ["privacyPolicy", "termsOfService"];
for (let propName of optionalStringProps) {
if (!aOptions[propName] || aOptions[propName] === "undefined")
continue;
if (typeof(aOptions[propName]) !== "string") {
throw new Error(propName + " must be a string representing a URL.");
}
if (aOptions[propName].length > MAX_STRING_LENGTH) {
throw new Error(propName + " is invalid.");
}
message[propName] = aOptions[propName];
}
if (aOptions["oncancel"]
&& typeof(aOptions["oncancel"]) !== "function") {
throw new Error("oncancel is not a function");
} else {
// Store optional cancel callback for later.
this._onCancelRequestCallback = aOptions.oncancel;
}
}
this._rpCalls++;
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Request", message);
},
logout: function nsDOMIdentity_logout() {
if (!this._rpWatcher) {
throw new Error("navigator.id.logout called before navigator.id.watch");
}
if (this._rpCalls > MAX_RP_CALLS) {
throw new Error("navigator.id.logout called too many times");
}
this._rpCalls++;
let message = this.DOMIdentityMessage();
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Logout", message);
},
/**
* Identity Provider (IDP) Provisioning APIs
*/
beginProvisioning: function nsDOMIdentity_beginProvisioning(aCallback) {
this._log("beginProvisioning");
if (this._beginProvisioningCallback) {
throw new Error("navigator.id.beginProvisioning already called.");
}
if (!aCallback || typeof(aCallback) !== "function") {
throw new Error("beginProvisioning callback is required.");
}
this._beginProvisioningCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginProvisioning",
this.DOMIdentityMessage());
},
genKeyPair: function nsDOMIdentity_genKeyPair(aCallback) {
this._log("genKeyPair");
if (!this._beginProvisioningCallback) {
throw new Error("navigator.id.genKeyPair called outside of provisioning");
}
if (this._genKeyPairCallback) {
throw new Error("navigator.id.genKeyPair already called.");
}
if (!aCallback || typeof(aCallback) !== "function") {
throw new Error("genKeyPair callback is required.");
}
this._genKeyPairCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:GenKeyPair",
this.DOMIdentityMessage());
},
registerCertificate: function nsDOMIdentity_registerCertificate(aCertificate) {
this._log("registerCertificate");
if (!this._genKeyPairCallback) {
throw new Error("navigator.id.registerCertificate called outside of provisioning");
}
if (this._provisioningEnded) {
throw new Error("Provisioning already ended");
}
this._provisioningEnded = true;
let message = this.DOMIdentityMessage();
message.cert = aCertificate;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:RegisterCertificate", message);
},
raiseProvisioningFailure: function nsDOMIdentity_raiseProvisioningFailure(aReason) {
this._log("raiseProvisioningFailure '" + aReason + "'");
if (this._provisioningEnded) {
throw new Error("Provisioning already ended");
}
if (!aReason || typeof(aReason) != "string") {
throw new Error("raiseProvisioningFailure reason is required");
}
this._provisioningEnded = true;
let message = this.DOMIdentityMessage();
message.reason = aReason;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:ProvisioningFailure", message);
},
/**
* Identity Provider (IDP) Authentication APIs
*/
beginAuthentication: function nsDOMIdentity_beginAuthentication(aCallback) {
this._log("beginAuthentication");
if (this._beginAuthenticationCallback) {
throw new Error("navigator.id.beginAuthentication already called.");
}
if (typeof(aCallback) !== "function") {
throw new Error("beginAuthentication callback is required.");
}
if (!aCallback || typeof(aCallback) !== "function") {
throw new Error("beginAuthentication callback is required.");
}
this._beginAuthenticationCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginAuthentication",
this.DOMIdentityMessage());
},
completeAuthentication: function nsDOMIdentity_completeAuthentication() {
if (this._authenticationEnded) {
throw new Error("Authentication already ended");
}
if (!this._beginAuthenticationCallback) {
throw new Error("navigator.id.completeAuthentication called outside of authentication");
}
this._authenticationEnded = true;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:CompleteAuthentication",
this.DOMIdentityMessage());
},
raiseAuthenticationFailure: function nsDOMIdentity_raiseAuthenticationFailure(aReason) {
if (this._authenticationEnded) {
throw new Error("Authentication already ended");
}
if (!aReason || typeof(aReason) != "string") {
throw new Error("raiseProvisioningFailure reason is required");
}
let message = this.DOMIdentityMessage();
message.reason = aReason;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:AuthenticationFailure", message);
},
// Private.
_init: function nsDOMIdentity__init(aWindow) {
this._initializeState();
// Store window and origin URI.
this._window = aWindow;
this._origin = aWindow.document.nodePrincipal.origin;
// Setup identifiers for current window.
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._id = util.outerWindowID;
},
/**
* Called during init and shutdown.
*/
_initializeState: function nsDOMIdentity__initializeState() {
// Some state to prevent abuse
// Limit the number of calls to .request
this._rpCalls = 0;
this._provisioningEnded = false;
this._authenticationEnded = false;
this._rpWatcher = null;
this._onCancelRequestCallback = null;
this._beginProvisioningCallback = null;
this._genKeyPairCallback = null;
this._beginAuthenticationCallback = null;
},
_receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) {
let msg = aMessage.json;
this._log("receiveMessage: " + aMessage.name);
switch (aMessage.name) {
case "Identity:ResetState":
if (!this._identityInternal._debug) {
return;
}
this._initializeState();
Services.obs.notifyObservers(null, "identity-DOM-state-reset", this._id);
break;
case "Identity:RP:Watch:OnLogin":
// Do we have a watcher?
if (!this._rpWatcher) {
return;
}
if (this._rpWatcher.onlogin) {
this._rpWatcher.onlogin(msg.assertion);
}
break;
case "Identity:RP:Watch:OnLogout":
// Do we have a watcher?
if (!this._rpWatcher) {
return;
}
if (this._rpWatcher.onlogout) {
this._rpWatcher.onlogout();
}
break;
case "Identity:RP:Watch:OnReady":
// Do we have a watcher?
if (!this._rpWatcher) {
return;
}
if (this._rpWatcher.onready) {
this._rpWatcher.onready();
}
break;
case "Identity:RP:Request:OnCancel":
// Do we have a watcher?
if (!this._rpWatcher) {
return;
}
if (this._onCancelRequestCallback) {
this._onCancelRequestCallback();
}
break;
case "Identity:IDP:CallBeginProvisioningCallback":
this._callBeginProvisioningCallback(msg);
break;
case "Identity:IDP:CallGenKeyPairCallback":
this._callGenKeyPairCallback(msg);
break;
case "Identity:IDP:CallBeginAuthenticationCallback":
this._callBeginAuthenticationCallback(msg);
break;
}
},
_log: function nsDOMIdentity__log(msg) {
this._identityInternal._log(msg);
},
_callGenKeyPairCallback: function nsDOMIdentity__callGenKeyPairCallback(message) {
// create a pubkey object that works
let chrome_pubkey = JSON.parse(message.publicKey);
// bunch of stuff to create a proper object in window context
function genPropDesc(value) {
return {
enumerable: true, configurable: true, writable: true, value: value
};
}
let propList = {};
for (let k in chrome_pubkey) {
propList[k] = genPropDesc(chrome_pubkey[k]);
}
let pubkey = Cu.createObjectIn(this._window);
Object.defineProperties(pubkey, propList);
Cu.makeObjectPropsNormal(pubkey);
// do the callback
this._genKeyPairCallback(pubkey);
},
_callBeginProvisioningCallback:
function nsDOMIdentity__callBeginProvisioningCallback(message) {
let identity = message.identity;
let certValidityDuration = message.certDuration;
this._beginProvisioningCallback(identity,
certValidityDuration);
},
_callBeginAuthenticationCallback:
function nsDOMIdentity__callBeginAuthenticationCallback(message) {
let identity = message.identity;
this._beginAuthenticationCallback(identity);
},
/**
* Helper to create messages to send using a message manager
*/
DOMIdentityMessage: function DOMIdentityMessage() {
return {
id: this._id,
origin: this._origin,
};
},
};
/**
* Internal functions that shouldn't be exposed to content.
*/
function nsDOMIdentityInternal() {
}
nsDOMIdentityInternal.prototype = {
// nsIFrameMessageListener
receiveMessage: function nsDOMIdentityInternal_receiveMessage(aMessage) {
let msg = aMessage.json;
// Is this message intended for this window?
if (msg.id != this._id) {
return;
}
this._identity._receiveMessage(aMessage);
},
// nsIObserver
observe: function nsDOMIdentityInternal_observe(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId != this._innerWindowID) {
return;
}
Services.obs.removeObserver(this, "inner-window-destroyed");
this._identity._initializeState();
this._identity = null;
// TODO: Also send message to DOMIdentity notifiying window is no longer valid
// ie. in the case that the user closes the auth. window and we need to know.
try {
for (let msgName of this._messages) {
this._mm.removeMessageListener(msgName, this);
}
} catch (ex) {
// Avoid errors when removing more than once.
}
this._mm = null;
},
// nsIDOMGlobalPropertyInitializer
init: function nsDOMIdentityInternal_init(aWindow) {
if (Services.prefs.getPrefType(PREF_ENABLED) != Ci.nsIPrefBranch.PREF_BOOL
|| !Services.prefs.getBoolPref(PREF_ENABLED)) {
return null;
}
this._debug =
Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
this._identity = new nsDOMIdentity(this);
this._identity._init(aWindow);
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._id = util.outerWindowID;
this._innerWindowID = util.currentInnerWindowID;
this._log("init was called from " + aWindow.document.location);
this._mm = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
// Setup listeners for messages from parent process.
this._messages = [
"Identity:ResetState",
"Identity:RP:Watch:OnLogin",
"Identity:RP:Watch:OnLogout",
"Identity:RP:Watch:OnReady",
"Identity:RP:Request:OnCancel",
"Identity:IDP:CallBeginProvisioningCallback",
"Identity:IDP:CallGenKeyPairCallback",
"Identity:IDP:CallBeginAuthenticationCallback",
];
this._messages.forEach((function(msgName) {
this._mm.addMessageListener(msgName, this);
}).bind(this));
// Setup observers so we can remove message listeners.
Services.obs.addObserver(this, "inner-window-destroyed", false);
return this._identity;
},
// Private.
_log: function nsDOMIdentityInternal__log(msg) {
if (!this._debug) {
return;
}
dump("nsDOMIdentity (" + this._id + "): " + msg + "\n");
},
// Component setup.
classID: Components.ID("{8bcac6a3-56a4-43a4-a44c-cdf42763002f}"),
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIFrameMessageListener]
),
classInfo: XPCOMUtils.generateCI({
classID: Components.ID("{8bcac6a3-56a4-43a4-a44c-cdf42763002f}"),
contractID: "@mozilla.org/dom/identity;1",
interfaces: [],
classDescription: "Identity DOM Implementation"
})
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentityInternal]);

View File

@ -1,34 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
function IDService() {
this.wrappedJSObject = this;
}
IDService.prototype = {
classID: Components.ID("{baa581e5-8e72-406c-8c9f-dcd4b23a6f82}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
observe: function observe(subject, topic, data) {
switch (topic) {
case "app-startup":
Services.obs.addObserver(this, "final-ui-startup", true);
break;
case "final-ui-startup":
// Startup DOMIdentity.jsm
Cu.import("resource://gre/modules/DOMIdentity.jsm");
DOMIdentity._init();
break;
}
}
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([IDService]);

View File

@ -1,28 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/identity/tests
include $(DEPTH)/config/autoconf.mk
DIRS = \
$(NULL)
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
head_identity.js \
test_identity_idp_auth_basics.html \
test_identity_idp_prov_basics.html \
test_identity_rp_basics.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

View File

@ -1,83 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const Ci = Components.interfaces;
const Cu = SpecialPowers.wrap(Components).utils;
SpecialPowers.setBoolPref("toolkit.identity.debug", true);
SpecialPowers.setBoolPref("dom.identity.enabled", true);
const Services = Cu.import("resource://gre/modules/Services.jsm").Services;
const DOMIdentity = Cu.import("resource://gre/modules/DOMIdentity.jsm")
.DOMIdentity;
let util = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let outerWinId = util.outerWindowID;
const identity = navigator.id || navigator.mozId;
let index = 0;
// mimicking callback funtionality for ease of testing
// this observer auto-removes itself after the observe function
// is called, so this is meant to observe only ONE event.
function makeObserver(aObserveTopic, aObserveFunc) {
function observe(aSubject, aTopic, aData) {
if (aTopic == aObserveTopic) {
aObserveFunc(aSubject, aTopic, aData);
Services.obs.removeObserver(this, aObserveTopic);
}
}
Services.obs.addObserver(observe, aObserveTopic, false);
}
function expectException(aFunc, msg, aErrorType="Error") {
info("Expecting an exception: " + msg);
msg = msg || "";
let caughtEx = null;
try {
aFunc();
} catch (ex) {
let exProto = Object.getPrototypeOf(ex);
// Don't count NS_* exceptions since they shouldn't be exposed to content
if (exProto.toString() == aErrorType
&& ex.toString().indexOf("NS_ERROR_FAILURE") == -1) {
caughtEx = ex;
} else {
ok(false, ex);
return;
}
}
isnot(caughtEx, null, "Check for thrown exception.");
}
function next() {
if (!identity) {
todo(false, "DOM API is not available. Skipping tests.");
finish_tests();
return;
}
if (index >= steps.length) {
ok(false, "Shouldn't get here!");
return;
}
try {
let fn = steps[index];
info("Begin test " + index + " '" + steps[index].name + "'!");
fn();
} catch(ex) {
ok(false, "Caught exception", ex);
}
index += 1;
}
function finish_tests() {
info("all done");
SpecialPowers.clearUserPref("toolkit.identity.debug");
SpecialPowers.clearUserPref("dom.identity.enabled");
SimpleTest.finish();
}

View File

@ -1,87 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<meta charset="utf-8">
<title>Test for navigator.id identity provider (IDP) authentication basics</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank">navigator.id identity provider (IDP) authentication basics</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
"use strict"
let steps = [
// completeAuthentication tests
function completeAuthenticationExists() {
is(typeof(identity.completeAuthentication), "function",
"Check completeAuthentication is a function");
SimpleTest.executeSoon(next);
},
function completeAuthenticationOutsideFlow() {
expectException(function() {
identity.completeAuthentication();
}, "Check completeAuthentication outside of an auth. flow");
SimpleTest.executeSoon(next);
},
// raiseAuthenticationFailure tests
function raiseAuthenticationFailureExists() {
is(typeof(identity.raiseAuthenticationFailure), "function",
"Check raiseAuthenticationFailure is a function");
SimpleTest.executeSoon(next);
},
function raiseAuthenticationFailureNoArgs() {
expectException(function() {
identity.raiseAuthenticationFailure();
}, "raiseAuthenticationFailure with no arguments");
SimpleTest.executeSoon(next);
},
// beginAuthentication tests
function beginAuthenticationExists() {
is(typeof(identity.beginAuthentication), "function",
"Check beginAuthentication is a function");
SimpleTest.executeSoon(next);
},
function beginAuthenticationNoArgs() {
expectException(function() {
identity.beginAuthentication();
}, "beginAuthentication with no arguments");
SimpleTest.executeSoon(next);
},
function beginAuthenticationInvalidArg() {
expectException(function() {
identity.beginAuthentication(999);
}, "beginAuthentication with a non-function argument");
SimpleTest.executeSoon(next);
},
function beginAuthenticationArgs() {
function beginAuthenticationCb() {
throw "beginAuthentication callback shouldn't have been called outside of an "
+ "auth flow";
}
is(identity.beginAuthentication(beginAuthenticationCb), undefined,
"Check minimum beginAuthentication arguments");
SimpleTest.executeSoon(next);
},
finish_tests,
];
SimpleTest.waitForExplicitFinish();
addLoadEvent(next);
</script>
</pre>
</body>
</html>

View File

@ -1,160 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<meta charset="utf-8">
<title>Test for navigator.id identity provider (IDP) provisioning basics</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank">navigator.id identity provider (IDP) provisioning basics</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
"use strict"
let IDP = Cu.import("resource://gre/modules/identity/IdentityProvider.jsm").IdentityProvider;
function setupProv() {
info("setupProv");
// Add a provisioning flow so the DOM calls succeed
IDP._provisionFlows[outerWinId] = {
sandbox: {},
callback: function doCallback(aErr) {
info("provisioning callback: " + aErr);
},
}
}
function resetAndNext() {
info("resetAndNext");
// reset DOM state for the next test
// Give the flow some time to cross the IPC boundary
setTimeout(function() {
let provContext = IDP._provisionFlows[outerWinId];
if (!provContext) {
SimpleTest.executeSoon(next);
return;
}
makeObserver("identity-DOM-state-reset", function() {
info("reset done");
SimpleTest.executeSoon(next);
});
DOMIdentity._resetFrameState(provContext.caller);
}, 500);
}
let steps = [
// genKeyPair tests
function genKeyPairExists() {
is(typeof(identity.genKeyPair), "function",
"Check genKeyPair is a function");
SimpleTest.executeSoon(next);
},
function genKeyPairOutsideProv() {
expectException(function(){
identity.genKeyPair(function(){});
}, "Check genKeyPair outside of a prov. flow");
SimpleTest.executeSoon(next);
},
function genKeyPairNoArgs() {
setupProv();
identity.beginProvisioning(function() {
expectException(function() {
identity.genKeyPair();
}, "genKeyPair with no arguments");
SimpleTest.executeSoon(resetAndNext);
});
},
function genKeyPairInvalidArg() {
setupProv();
identity.beginProvisioning(function() {
expectException(function() {
identity.genKeyPair(999);
}, "Check genKeyPair with non-function object argument");
SimpleTest.executeSoon(resetAndNext);
});
},
// registerCertificate tests
function registerCertificateExists() {
is(typeof(identity.registerCertificate), "function",
"Check registerCertificate is a function");
SimpleTest.executeSoon(next);
},
function registerCertificateNoArgs() {
setupProv();
identity.beginProvisioning(function() {
expectException(function() {
identity.registerCertificate();
}, "Check registerCertificate with no arguments");
});
SimpleTest.executeSoon(resetAndNext);
},
function registerCertificateOutsideProv() {
expectException(function(){
identity.registerCertificate("foo");
}, "Check registerCertificate outside of a prov. flow");
SimpleTest.executeSoon(next);
},
// raiseProvisioningFailure tests
function raiseProvisioningFailureExists() {
is(typeof(identity.raiseProvisioningFailure), "function",
"Check raiseProvisioningFailure is a function");
SimpleTest.executeSoon(next);
},
function raiseProvisioningFailureNoArgs() {
expectException(function() {
identity.raiseProvisioningFailure();
}, "raiseProvisioningFailure with no arguments");
SimpleTest.executeSoon(next);
},
function raiseProvisioningFailureWithReason() {
identity.raiseProvisioningFailure("my test reason");
SimpleTest.executeSoon(next);
},
// beginProvisioning tests
function beginProvisioningExists() {
is(typeof(identity.beginProvisioning), "function",
"Check beginProvisioning is a function");
SimpleTest.executeSoon(next);
},
function beginProvisioningNoArgs() {
expectException(function() {
identity.beginProvisioning();
}, "beginProvisioning with no arguments");
SimpleTest.executeSoon(next);
},
function beginProvisioningInvalidArg() {
expectException(function() {
identity.beginProvisioning(999);
}, "beginProvisioning with a non-function argument");
SimpleTest.executeSoon(next);
},
function beginProvisioningArgs() {
function beginProvisioningCb() {
SimpleTest.executeSoon(resetAndNext);
}
is(identity.beginProvisioning(beginProvisioningCb), undefined,
"Check minimum beginProvisioning arguments");
},
finish_tests,
];
SimpleTest.waitForExplicitFinish();
addLoadEvent(next);
</script>
</pre>
</body>
</html>

View File

@ -1,172 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<meta charset="utf-8">
<title>Test for navigator.id relying party (RP) basics</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank">navigator.id RP basics</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
"use strict";
const RP = Cu.import("resource://gre/modules/identity/RelyingParty.jsm").RelyingParty;
function resetAndNext() {
// reset DOM state for the next test
makeObserver("identity-DOM-state-reset", function() {
SimpleTest.executeSoon(next);
});
// Give the flow some time to cross the IPC boundary
setTimeout(function() {
let rpContext = RP._rpFlows[outerWinId];
if (!rpContext) {
SimpleTest.executeSoon(next);
return;
}
DOMIdentity._resetFrameState(rpContext);
}, 500);
}
let steps = [
function nonExistentProp() {
is(identity.foobarbaz, undefined, "Check that foobarbaz does not exist");
expectException(function() {
identity.foobarbaz()
}, "Check for exception calling non-existent method", "TypeError");
SimpleTest.executeSoon(next);
},
// test request before watch throws an exception
function requestBeforeWatch() {
expectException(function() {
identity.request();
});
SimpleTest.executeSoon(next);
},
// watch tests
function watchExists() {
is(typeof(identity.watch), "function", "Check watch is a function");
SimpleTest.executeSoon(next);
},
function watchNoArgs() {
expectException(function() {
identity.watch();
}, "watch with no arguments");
SimpleTest.executeSoon(next);
},
function watchEmptyObj() {
expectException(function() {
identity.watch({});
}, "watch with empty object argument");
SimpleTest.executeSoon(next);
},
function watchOnLoginBool() {
expectException(function() {
identity.watch({onlogin: true});
}, "watch with invalid onlogin member");
SimpleTest.executeSoon(next);
},
function watchOnLoginLogoutBool() {
expectException(function() {
identity.watch({onlogin: true, onlogout: false});
}, "watch with invalid onlogin and onlogout members");
SimpleTest.executeSoon(next);
},
function watchMinimumArgs() {
function onLoginLogoutCb() {
throw "onlogin/onlogout callback shouldn't have been called";
}
is(identity.watch({onlogin: onLoginLogoutCb, onlogout: onLoginLogoutCb}),
undefined, "Check minimum watch argument members");
resetAndNext();
},
function watchOnReadyType() {
function onLoginLogoutCb() {
throw "onlogin/onlogout callback shouldn't have been called";
}
let options = {
onlogin: onLoginLogoutCb,
onlogout: onLoginLogoutCb,
onready: 999,
}
expectException(function() {
identity.watch(options)
}, "Check onready type");
resetAndNext();
},
function watchLoggedInEmailType() {
function onLoginLogoutCb() {
throw "onlogin/onlogout callback shouldn't have been called";
}
let options = {
onlogin: onLoginLogoutCb,
onlogout: onLoginLogoutCb,
loggedInEmail: {},
}
expectException(function() {
identity.watch(options)
}, "Check loggedInEmail type");
resetAndNext();
},
function watchOnReadyCalled() {
let onLogoutCalled = false;
let options = {
loggedInEmail: "loggedOut@user.com",
onlogin: function onLoginCb(assertion) {
throw "onlogin/onlogout callback shouldn't have been called";
},
onlogout: function onLogoutCb() {
is(arguments.length, 0, "Check onlogout argument length");
onLogoutCalled = true;
},
onready: function onReady() {
is(arguments.length, 0, "Check onready argument length");
ok(onLogoutCalled, "onlogout callback should be called before onready");
SimpleTest.executeSoon(next);
},
}
is(identity.watch(options), undefined, "Check onready is called");
},
// request tests
function requestExists() {
is(typeof(identity.request), "function", "Check request is a function");
SimpleTest.executeSoon(next);
},
function requestNoArgs() {
is(identity.request(), undefined, "Check request with no arguments");
SimpleTest.executeSoon(next);
},
function requestEmptyObj() {
is(identity.request({}), undefined, "Check request with empty object argument");
SimpleTest.executeSoon(next);
},
// logout tests
function logoutExists() {
is(typeof(identity.logout), "function", "Check logout is a function");
SimpleTest.executeSoon(next);
},
finish_tests,
];
SimpleTest.waitForExplicitFinish();
addLoadEvent(next);
</script>
</pre>
</body>
</html>

View File

@ -42,7 +42,6 @@ function IdentityProviderService() {
IdentityProviderService.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
_sandboxConfigured: false,
observe: function observe(aSubject, aTopic, aData) {
switch (aTopic) {
@ -84,14 +83,6 @@ IdentityProviderService.prototype = {
shutdown: function RP_shutdown() {
this.reset();
if (this._sandboxConfigured) {
// Tear down message manager listening on the hidden window
Cu.import("resource://gre/modules/DOMIdentity.jsm");
DOMIdentity._configureMessages(Services.appShell.hiddenDOMWindow, false);
this._sandboxConfigured = false;
}
Services.obs.removeObserver(this, "quit-application-granted");
},
@ -441,14 +432,6 @@ IdentityProviderService.prototype = {
*/
_createProvisioningSandbox: function _createProvisioningSandbox(aURL, aCallback) {
log("_createProvisioningSandbox:", aURL);
if (!this._sandboxConfigured) {
// Configure message manager listening on the hidden window
Cu.import("resource://gre/modules/DOMIdentity.jsm");
DOMIdentity._configureMessages(Services.appShell.hiddenDOMWindow, true);
this._sandboxConfigured = true;
}
new Sandbox(aURL, aCallback);
},

View File

@ -13,6 +13,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = test_identity
XPCSHELL_TESTS = unit
DIRS = chrome mochitest
DIRS = chrome
include $(topsrcdir)/config/rules.mk

View File

@ -1,22 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = toolkit/identity/tests/mochitest
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
head_identity.js \
test_authentication.html \
test_provisioning.html \
test_relying_party.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

View File

@ -1,202 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/** Helper functions for identity mochitests **/
/** Please keep functions in-sync with unit/head_identity.js **/
"use strict";
const Cc = SpecialPowers.wrap(Components).classes;
const Ci = Components.interfaces;
const Cu = SpecialPowers.wrap(Components).utils;
const TEST_URL = "http://mochi.test:8888";
const TEST_URL2 = "https://myfavoritebaconinacan.com";
const TEST_USER = "user@example.com";
const TEST_PRIVKEY = "fake-privkey";
const TEST_CERT = "fake-cert";
const TEST_IDPPARAMS = {
domain: "example.com",
idpParams: {
authentication: "/foo/authenticate.html",
provisioning: "/foo/provision.html"
},
};
const Services = Cu.import("resource://gre/modules/Services.jsm").Services;
// Set the debug pref before loading other modules
SpecialPowers.setBoolPref("toolkit.identity.debug", true);
SpecialPowers.setBoolPref("dom.identity.enabled", true);
const jwcrypto = Cu.import("resource://gre/modules/identity/jwcrypto.jsm").jwcrypto;
const IdentityStore = Cu.import("resource://gre/modules/identity/IdentityStore.jsm").IdentityStore;
const RelyingParty = Cu.import("resource://gre/modules/identity/RelyingParty.jsm").RelyingParty;
const XPCOMUtils = Cu.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils;
const IDService = Cu.import("resource://gre/modules/identity/Identity.jsm").IdentityService;
const IdentityProvider = Cu.import("resource://gre/modules/identity/IdentityProvider.jsm").IdentityProvider;
const identity = navigator.id || navigator.mozId;
function do_check_null(aVal, aMsg) {
is(aVal, null, aMsg);
}
function do_timeout(aDelay, aFunc) {
setTimeout(aFunc, aDelay);
}
function get_idstore() {
return IdentityStore;
}
// create a mock "watch" object, which the Identity Service
function mock_watch(aIdentity, aDoFunc) {
function partial(fn) {
let args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
};
}
let mockedWatch = {};
mockedWatch.loggedInEmail = aIdentity;
mockedWatch['do'] = aDoFunc;
mockedWatch.onready = partial(aDoFunc, 'ready');
mockedWatch.onlogin = partial(aDoFunc, 'login');
mockedWatch.onlogout = partial(aDoFunc, 'logout');
return mockedWatch;
}
// mimicking callback funtionality for ease of testing
// this observer auto-removes itself after the observe function
// is called, so this is meant to observe only ONE event.
function makeObserver(aObserveTopic, aObserveFunc) {
function observe(aSubject, aTopic, aData) {
if (aTopic == aObserveTopic) {
Services.obs.removeObserver(this, aObserveTopic);
try {
aObserveFunc(SpecialPowers.wrap(aSubject), aTopic, aData);
} catch (ex) {
ok(false, ex);
}
}
}
Services.obs.addObserver(observe, aObserveTopic, false);
}
// set up the ID service with an identity with keypair and all
// when ready, invoke callback with the identity
function setup_test_identity(identity, cert, cb) {
// set up the store so that we're supposed to be logged in
let store = get_idstore();
function keyGenerated(err, kpo) {
store.addIdentity(identity, kpo, cert);
cb();
};
jwcrypto.generateKeyPair("DS160", keyGenerated);
}
// takes a list of functions and returns a function that
// when called the first time, calls the first func,
// then the next time the second, etc.
function call_sequentially() {
let numCalls = 0;
let funcs = arguments;
return function() {
if (!funcs[numCalls]) {
let argString = Array.prototype.slice.call(arguments).join(",");
ok(false, "Too many calls: " + argString);
return;
}
funcs[numCalls].apply(funcs[numCalls], arguments);
numCalls += 1;
};
}
/*
* Setup a provisioning workflow with appropriate callbacks
*
* identity is the email we're provisioning.
*
* afterSetupCallback is required.
*
* doneProvisioningCallback is optional, if the caller
* wants to be notified when the whole provisioning workflow is done
*
* frameCallbacks is optional, contains the callbacks that the sandbox
* frame would provide in response to DOM calls.
*/
function setup_provisioning(identity, afterSetupCallback, doneProvisioningCallback, callerCallbacks) {
IDService.reset();
let util = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let provId = util.outerWindowID;
IDService.IDP._provisionFlows[provId] = {
identity : identity,
idpParams: TEST_IDPPARAMS,
callback: function(err) {
if (doneProvisioningCallback)
doneProvisioningCallback(err);
},
sandbox: {
// Emulate the free() method on the iframe sandbox
free: function() {}
}
};
let caller = {};
caller.id = callerCallbacks.id = provId;
caller.doBeginProvisioningCallback = function(id, duration_s) {
if (callerCallbacks && callerCallbacks.beginProvisioningCallback)
callerCallbacks.beginProvisioningCallback(id, duration_s);
};
caller.doGenKeyPairCallback = function(pk) {
if (callerCallbacks && callerCallbacks.genKeyPairCallback)
callerCallbacks.genKeyPairCallback(pk);
};
afterSetupCallback(callerCallbacks);
}
function resetState() {
get_idstore().reset();
RelyingParty.reset();
}
function cleanup() {
SpecialPowers.clearUserPref("toolkit.identity.debug");
SpecialPowers.clearUserPref("dom.identity.enabled");
}
var TESTS = [];
function run_next_test() {
if (!identity) {
todo(false, "DOM API is not available. Skipping tests.");
cleanup();
SimpleTest.finish();
return;
}
if (TESTS.length) {
let test = TESTS.shift();
info(test.name);
try {
test();
} catch (ex) {
ok(false, ex);
}
} else {
cleanup();
info("all done");
SimpleTest.finish();
}
}

View File

@ -1,179 +0,0 @@
<!DOCTYPE html>
<html>
<!--
Test of Identity Provider (IDP) Authentication using the DOM APIs
-->
<head>
<meta charset="utf-8">
<title>Test of Identity Provider (IDP) Authentication using the DOM APIs</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
</head>
<body onload="run_next_test()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753238">Test of Identity Provider (IDP) Authentication using the DOM APIs</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
/** Test of Identity Provider (IDP) Authentication using the DOM APIs **/
/** Most tests are ported from test_authentication.js */
"use strict";
SimpleTest.waitForExplicitFinish();
const DOMIdentity = Cu.import("resource://gre/modules/DOMIdentity.jsm")
.DOMIdentity;
let outerWinId = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
function run_next_auth_test() {
// Reset the DOM state then run the next test
let provContext = IdentityProvider._provisionFlows[outerWinId];
if (provContext && provContext.caller) {
makeObserver("identity-DOM-state-reset", function() {
SimpleTest.executeSoon(run_next_test);
});
DOMIdentity._resetFrameState(provContext.caller);
} else {
SimpleTest.executeSoon(run_next_test);
}
}
function test_begin_authentication_flow() {
let _provId = null;
// set up a watch, to be consistent
let mockedDoc = mock_watch(null, function(action, params) {});
identity.watch(mockedDoc);
// The identity-auth notification is sent up to the UX from the
// _doAuthentication function. Be ready to receive it and call
// beginAuthentication
makeObserver("identity-auth", function (aSubject, aTopic, aData) {
isnot(aSubject, null);
is(aSubject.wrappedJSObject.provId, _provId);
run_next_auth_test();
});
setup_provisioning(
TEST_USER,
function(caller) {
_provId = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
}, function() {},
{
beginProvisioningCallback: function(email, duration_s) {
// let's say this user needs to authenticate
IDService.IDP._doAuthentication(_provId, TEST_IDPPARAMS);
}
});
}
function test_complete_authentication_flow() {
let _provId = null;
let _authId = null;
let id = TEST_USER;
let callbacksFired = false;
let topicObserved = false;
// The result of authentication should be a successful login
IDService.reset();
setup_test_identity(id, TEST_CERT, function() {
// When we authenticate, our ready callback will be fired.
// At the same time, a separate topic will be sent up to the
// the observer in the UI. The test is complete when both
// events have occurred.
let mockedDoc = mock_watch(null, call_sequentially(
function(action, params) {
is(action, 'ready');
is(params, undefined);
// if notification already received by observer, test is done
callbacksFired = true;
if (topicObserved) {
run_next_auth_test();
}
}
));
makeObserver("identity-login-state-changed", function (aSubject, aTopic, aData) {
info("identity-login-state-changed");
isnot(aSubject, null);
//is(aSubject.wrappedJSObject.rpId, mockedDoc.id);
is(aData, null);
// if callbacks in caller doc already fired, test is done.
topicObserved = true;
if (callbacksFired) {
run_next_auth_test();
}
});
identity.watch(mockedDoc);
});
// A mock calling context
let authCaller = {
doBeginAuthenticationCallback: function doBeginAuthenticationCallback(aIdentity) {
is(aIdentity, TEST_USER);
identity.completeAuthentication();
},
doError: function(err) {
ok(false, "OW! My doError callback hurts!: " + err);
},
};
makeObserver("identity-auth-complete", function (aSubject, aTopic, aData) {
is(aSubject.wrappedJSObject.identity, TEST_USER);
run_next_test();
});
// Create a provisioning flow for our auth flow to attach to
setup_provisioning(
TEST_USER,
function(provFlow) {
_provId = provFlow.id;
identity.beginProvisioning(provFlow.beginProvisioningCallback);
}, function() {},
{
beginProvisioningCallback: function(email, duration_s) {
// let's say this user needs to authenticate
IDService.IDP._doAuthentication(_provId, TEST_IDPPARAMS);
// test_begin_authentication_flow verifies that the right
// message is sent to the UI. So that works. Moving on,
// the UI calls setAuthenticationFlow ...
_authId = outerWinId;
IDService.IDP.setAuthenticationFlow(_authId, _provId);
// ... then the UI calls beginAuthentication ...
authCaller.id = _authId;
IDService.IDP._provisionFlows[_provId].caller = authCaller;
identity.beginAuthentication(function bac() {
info("beginAuthentication callback");
identity.completeAuthentication();
});
}
});
}
TESTS.push(test_begin_authentication_flow);
TESTS.push(test_complete_authentication_flow);
</script>
</pre>
</body>
</html>

View File

@ -1,286 +0,0 @@
<!DOCTYPE html>
<html>
<!--
Test of Identity Provider (IDP) Provisioning using the DOM APIs
-->
<head>
<meta charset="utf-8">
<title>Test of Identity Provider (IDP) Provisioning using the DOM APIs</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
</head>
<body onload="run_next_test()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753238">Test of Identity Provider (IDP) Provisioning using the DOM APIs</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
/** Test of Identity Provider (IDP) Provisioning using the DOM APIs **/
/** Most tests are ported from test_provisioning.js */
"use strict";
SimpleTest.waitForExplicitFinish();
const DOMIdentity = Cu.import("resource://gre/modules/DOMIdentity.jsm")
.DOMIdentity;
let outerWinId = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
function check_provision_flow_done(provId) {
do_check_null(IdentityProvider._provisionFlows[provId]);
}
/**
* Allow specifying aProvFlow so we can reset after the _provisionFlows is cleaned up.
*/
function run_next_prov_test(aProvFlow) {
// Reset the DOM state then run the next test
let provContext = aProvFlow || IdentityProvider._provisionFlows[outerWinId];
if (provContext && provContext.caller) {
makeObserver("identity-DOM-state-reset", function() {
SimpleTest.executeSoon(run_next_test);
});
DOMIdentity._resetFrameState(provContext.caller);
} else {
SimpleTest.executeSoon(run_next_test);
}
}
function test_begin_provisioning() {
setup_provisioning(
TEST_USER,
function(caller) {
// call .beginProvisioning()
// TODO: should probably throw outside of a prov. sandbox?
identity.beginProvisioning(caller.beginProvisioningCallback);
}, function() {},
{
beginProvisioningCallback: function(email, duration_s) {
is(email, TEST_USER);
ok(duration_s > 0);
ok(duration_s <= (24 * 3600));
run_next_prov_test();
}
});
}
function test_raise_provisioning_failure() {
let _callerId = null;
setup_provisioning(
TEST_USER,
function(caller) {
// call .beginProvisioning()
_callerId = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
}, function(err) {
// this should be invoked with a populated error
isnot(err, null);
ok(err.indexOf("can't authenticate this email") > -1);
run_next_prov_test();
},
{
beginProvisioningCallback: function(email, duration_s) {
// raise the failure as if we can't provision this email
identity.raiseProvisioningFailure("can't authenticate this email");
}
});
}
function test_genkeypair_before_begin_provisioning() {
setup_provisioning(
TEST_USER,
function(caller) {
try {
// call genKeyPair without beginProvisioning
identity.genKeyPair(caller.genKeyPairCallback);
} catch (ex) {
ok(ex, "Caught exception for calling genKeyPair without beginProvisioning: " + ex);
run_next_prov_test();
}
},
// expect this to be called with an error
function(err) {
ok(false, "Shoudn't reach here as DOM code should have caught the problem");
run_next_prov_test();
},
{
// this should not be called at all!
genKeyPairCallback: function(pk) {
// a test that will surely fail because we shouldn't be here.
ok(false);
run_next_prov_test();
}
}
);
}
function test_genkeypair() {
let _callerId = null;
function gkpCallback(kp) {
isnot(kp, null);
// yay!
run_next_prov_test();
}
setup_provisioning(
TEST_USER,
function(caller) {
_callerId = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
},
function(err) {
// should not be called!
ok(false);
run_next_prov_test();
},
{
beginProvisioningCallback: function(email, time_s) {
identity.genKeyPair(gkpCallback);
},
genKeyPairCallback: gkpCallback,
}
);
}
// we've already ensured that genkeypair can't be called
// before beginProvisioning, so this test should be enough
// to ensure full sequential call of the 3 APIs.
function test_register_certificate_before_genkeypair() {
let _callerID = null;
setup_provisioning(
TEST_USER,
function(caller) {
// do the right thing for beginProvisioning
_callerID = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
},
// expect this to be called with an error
function(err) {
ok(false, "Shoudn't reach here as DOM code should have caught the problem");
run_next_prov_test();
},
{
beginProvisioningCallback: function(email, duration_s) {
try {
// now we try to register cert but no keygen has been done
identity.registerCertificate("fake-cert");
} catch (ex) {
ok(ex, "Caught exception for calling genKeyPair without beginProvisioning: " + ex);
run_next_prov_test();
}
}
}
);
}
function test_register_certificate() {
let _callerId = null;
let provFlow = null;
function gkpCallback(pk) {
// Hold on to the provFlow so we have access to .caller to cleanup later
provFlow = IdentityProvider._provisionFlows[outerWinId];
identity.registerCertificate("fake-cert-42");
}
setup_provisioning(
TEST_USER,
function(caller) {
_callerId = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
},
function(err) {
// we should be cool!
do_check_null(err);
// check that the cert is there
let identity = get_idstore().fetchIdentity(TEST_USER);
isnot(identity,null);
is(identity.cert, "fake-cert-42");
SimpleTest.executeSoon(function check_done() {
// cleanup will happen after the callback is called
check_provision_flow_done(_callerId);
run_next_prov_test(provFlow);
});
},
{
beginProvisioningCallback: function(email, duration_s) {
identity.genKeyPair(gkpCallback);
},
genKeyPairCallback: gkpCallback,
}
);
}
function test_get_assertion_after_provision() {
let _callerId = null;
let provFlow = null;
function gkpCallback(pk) {
// Hold on to the provFlow so we have access to .caller to cleanup later
provFlow = IdentityProvider._provisionFlows[outerWinId];
identity.registerCertificate("fake-cert-42");
}
setup_provisioning(
TEST_USER,
function(caller) {
_callerId = caller.id;
identity.beginProvisioning(caller.beginProvisioningCallback);
},
function(err) {
// we should be cool!
do_check_null(err);
// check that the cert is there
let identity = get_idstore().fetchIdentity(TEST_USER);
isnot(identity,null);
is(identity.cert, "fake-cert-42");
SimpleTest.executeSoon(function check_done() {
// cleanup will happen after the callback is called
check_provision_flow_done(_callerId);
run_next_prov_test(provFlow);
});
},
{
beginProvisioningCallback: function(email, duration_s) {
identity.genKeyPair(gkpCallback);
},
genKeyPairCallback: gkpCallback,
}
);
}
TESTS.push(test_genkeypair_before_begin_provisioning);
TESTS.push(test_begin_provisioning);
TESTS.push(test_raise_provisioning_failure);
TESTS.push(test_register_certificate_before_genkeypair);
TESTS.push(test_genkeypair);
TESTS.push(test_register_certificate);
TESTS.push(test_get_assertion_after_provision);
</script>
</pre>
</body>
</html>

View File

@ -1,223 +0,0 @@
<!DOCTYPE html>
<html>
<!--
Test of Relying Party (RP) using the DOM APIs
-->
<head>
<meta charset="utf-8">
<title>Test of Relying Party (RP) using the DOM APIs</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8" src="head_identity.js"></script>
</head>
<body onload="run_next_test()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753238">Test of Relying Party (RP) using the DOM APIs</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.8">
/** Test of Relying Party (RP) using the DOM APIs **/
/** Most tests are ported from test_relying_party.js */
"use strict";
SimpleTest.waitForExplicitFinish();
const DOMIdentity = Cu.import("resource://gre/modules/DOMIdentity.jsm")
.DOMIdentity;
let outerWinId = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
// Reset the DOM state then run the next test
function run_next_rp_test() {
let rpContext = RelyingParty._rpFlows[outerWinId];
if (rpContext) {
makeObserver("identity-DOM-state-reset", function() {
SimpleTest.executeSoon(run_next_test);
});
DOMIdentity._resetFrameState(rpContext);
} else {
SimpleTest.executeSoon(run_next_test);
}
}
function test_watch_loggedin_ready() {
resetState();
let id = TEST_USER;
setup_test_identity(id, TEST_CERT, function() {
let store = get_idstore();
// set it up so we're supposed to be logged in to TEST_URL
store.setLoginState(TEST_URL, true, id);
identity.watch(mock_watch(id, function(action, params) {
is(action, 'ready');
is(params, undefined);
run_next_rp_test();
}));
});
}
function test_watch_loggedin_login() {
resetState();
let id = TEST_USER;
setup_test_identity(id, TEST_CERT, function() {
let store = get_idstore();
// set it up so we're supposed to be logged in to TEST_URL
store.setLoginState(TEST_URL, true, id);
// check for first a login() call, then a ready() call
identity.watch(mock_watch(null, call_sequentially(
function(action, params) {
is(action, 'login');
isnot(params, null);
},
function(action, params) {
is(action, 'ready');
do_check_null(params);
run_next_rp_test();
}
)));
});
}
function test_watch_loggedin_logout() {
resetState();
let id = TEST_USER;
let other_id = "otherid@foo.com";
setup_test_identity(other_id, TEST_CERT, function() {
setup_test_identity(id, TEST_CERT, function() {
let store = get_idstore();
// set it up so we're supposed to be logged in to TEST_URL
// with id, not other_id
store.setLoginState(TEST_URL, true, id);
// this should cause a login with an assertion for id,
// not for other_id
identity.watch(mock_watch(other_id, call_sequentially(
function(action, params) {
is(action, 'login');
isnot(params, null);
},
function(action, params) {
is(action, 'ready');
do_check_null(params);
run_next_rp_test();
}
)));
});
});
}
function test_watch_notloggedin_ready() {
resetState();
identity.watch(mock_watch(null, function(action, params) {
is(action, 'ready');
is(params, undefined);
run_next_rp_test();
}));
}
function test_watch_notloggedin_logout() {
resetState();
identity.watch(mock_watch(TEST_USER, call_sequentially(
function(action, params) {
is(action, 'logout');
is(params, undefined);
let store = get_idstore();
do_check_null(store.getLoginState(TEST_URL));
},
function(action, params) {
is(action, 'ready');
is(params, undefined);
run_next_rp_test();
}
)));
}
function test_request() {
// set up a watch, to be consistent
let mockedDoc = mock_watch(null, function(action, params) {
// We're not checking anything here at the moment.
});
identity.watch(mockedDoc);
// be ready for the UX identity-request notification
makeObserver("identity-request", function (aSubject, aTopic, aData) {
isnot(aSubject, null);
run_next_rp_test();
});
identity.request();
}
function test_logout() {
resetState();
let id = TEST_USER;
setup_test_identity(id, TEST_CERT, function() {
let store = get_idstore();
// set it up so we're supposed to be logged in to TEST_URL
store.setLoginState(TEST_URL, true, id);
let doLogout;
let mockedDoc = mock_watch(id, call_sequentially(
function(action, params) {
is(action, 'ready');
is(params, undefined);
SimpleTest.executeSoon(doLogout);
},
function(action, params) {
is(action, 'logout');
is(params, undefined);
},
function(action, params) {
is(action, 'ready');
is(params, undefined);
run_next_rp_test();
}));
doLogout = function() {
makeObserver("identity-login-state-changed", function (aSubject, aTopic, aData) {
isnot(aSubject.wrappedJSObject.rpId, null, "Check rpId is not null");
is(aData, null, "Check identity changed to nobody");
ok(!store.getLoginState(TEST_URL).isLoggedIn, "Check isLoggedIn is false");
is(store.getLoginState(TEST_URL).email, TEST_USER, "Check notification email");
});
identity.logout();
};
identity.watch(mockedDoc);
});
}
TESTS = TESTS.concat([test_watch_loggedin_ready, test_watch_loggedin_login, test_watch_loggedin_logout]);
TESTS = TESTS.concat([test_watch_notloggedin_ready, test_watch_notloggedin_logout]);
TESTS.push(test_request);
TESTS.push(test_logout);
</script>
</pre>
</body>
</html>

View File

@ -10,8 +10,8 @@ tail = tail_identity.js
[test_crypto_service.js]
[test_identity.js]
[test_jwcrypto.js]
[test_observer_topics.js]
[test_provisioning.js]
[test_relying_party.js]
[test_store.js]
[test_well-known.js]
[test_observer_topics.js]

View File

@ -875,7 +875,6 @@ if [ "$ENABLE_TESTS" ]; then
toolkit/devtools/debugger/tests/Makefile
toolkit/identity/tests/Makefile
toolkit/identity/tests/chrome/Makefile
toolkit/identity/tests/mochitest/Makefile
toolkit/mozapps/downloads/tests/Makefile
toolkit/mozapps/downloads/tests/chrome/Makefile
toolkit/mozapps/extensions/test/Makefile