author | Jed Parsons <jedp@mozilla.com> |
Fri, 30 May 2014 17:06:18 -0700 | |
changeset 232128 | f70e16de6f33742ae387b1f38d1aa960667b3cda |
parent 232127 | 4de43ef387d279e6eadefcb39c34a828822a7911 |
child 232129 | 90f8728118e8ba7018cf9e80bf2f739ce64d0575 |
push id | 4187 |
push user | bhearsum@mozilla.com |
push date | Fri, 28 Nov 2014 15:29:12 +0000 |
treeherder | mozilla-beta@f23cc6a30c11 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bholley, spenrose, jst |
bugs | 1011084 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/identity/Identity.manifest +++ b/dom/identity/Identity.manifest @@ -1,9 +1,8 @@ # nsDOMIdentity.js component {210853d9-2c97-4669-9761-b1ab9cbf57ef} nsDOMIdentity.js -contract @mozilla.org/dom/identity;1 {210853d9-2c97-4669-9761-b1ab9cbf57ef} -category JavaScript-navigator-property mozId @mozilla.org/dom/identity;1 +contract @mozilla.org/identity/manager;1 {210853d9-2c97-4669-9761-b1ab9cbf57ef} # nsIDService.js (initialization on startup) component {4e0a0e98-b1d3-4745-a1eb-f815199dd06b} nsIDService.js contract @mozilla.org/dom/identity/service;1 {4e0a0e98-b1d3-4745-a1eb-f815199dd06b} category app-startup IDService @mozilla.org/dom/identity/service;1
--- a/dom/identity/nsDOMIdentity.js +++ b/dom/identity/nsDOMIdentity.js @@ -41,39 +41,20 @@ XPCOMUtils.defineLazyServiceGetter(this, const ERRORS = { "ERROR_INVALID_ASSERTION_AUDIENCE": "Assertion audience may not differ from origin", "ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT": "The request() method may only be invoked when handling user input", }; -function nsDOMIdentity(aIdentityInternal) { - this._identityInternal = aIdentityInternal; +function nsDOMIdentity() { } -nsDOMIdentity.prototype = { - __exposedProps__: { - // Relying Party (RP) - watch: 'r', - request: 'r', - logout: 'r', - get: 'r', - getVerifiedEmail: 'r', - // Provisioning - beginProvisioning: 'r', - genKeyPair: 'r', - registerCertificate: 'r', - raiseProvisioningFailure: 'r', - - // Authentication - beginAuthentication: 'r', - completeAuthentication: 'r', - raiseAuthenticationFailure: 'r' - }, +nsDOMIdentity.prototype = { // require native events unless syntheticEventsOk is set get nativeEventsRequired() { if (Services.prefs.prefHasUserValue(PREF_SYNTHETIC_EVENTS_OK) && (Services.prefs.getPrefType(PREF_SYNTHETIC_EVENTS_OK) === Ci.nsIPrefBranch.PREF_BOOL)) { return !Services.prefs.getBoolPref(PREF_SYNTHETIC_EVENTS_OK); } @@ -143,17 +124,17 @@ nsDOMIdentity.prototype = { this._rpWatcher.audience = message.audience; if (message.errors.length) { this.reportErrors(message); // We don't delete the rpWatcher object, because we don't want the // broken client to be able to call watch() any more. It's broken. return; } - this._identityInternal._mm.sendAsyncMessage( + this._mm.sendAsyncMessage( "Identity:RP:Watch", message, null, this._window.document.nodePrincipal ); }, request: function nsDOMIdentity_request(aOptions = {}) { @@ -219,17 +200,17 @@ nsDOMIdentity.prototype = { 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( + this._mm.sendAsyncMessage( "Identity:RP:Request", message, null, this._window.document.nodePrincipal ); }, logout: function nsDOMIdentity_logout() { @@ -244,17 +225,17 @@ nsDOMIdentity.prototype = { let message = this.DOMIdentityMessage(); // Report and fail hard on any errors. if (message.errors.length) { this.reportErrors(message); return; } - this._identityInternal._mm.sendAsyncMessage( + this._mm.sendAsyncMessage( "Identity:RP:Logout", message, null, this._window.document.nodePrincipal ); }, /* @@ -332,17 +313,17 @@ nsDOMIdentity.prototype = { 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( + this._mm.sendAsyncMessage( "Identity:IDP:BeginProvisioning", this.DOMIdentityMessage(), null, this._window.document.nodePrincipal ); }, genKeyPair: function nsDOMIdentity_genKeyPair(aCallback) { @@ -353,17 +334,17 @@ nsDOMIdentity.prototype = { 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( + this._mm.sendAsyncMessage( "Identity:IDP:GenKeyPair", this.DOMIdentityMessage(), null, this._window.document.nodePrincipal ); }, registerCertificate: function nsDOMIdentity_registerCertificate(aCertificate) { @@ -373,17 +354,17 @@ nsDOMIdentity.prototype = { } if (this._provisioningEnded) { throw new Error("Provisioning already ended"); } this._provisioningEnded = true; let message = this.DOMIdentityMessage(); message.cert = aCertificate; - this._identityInternal._mm.sendAsyncMessage( + this._mm.sendAsyncMessage( "Identity:IDP:RegisterCertificate", message, null, this._window.document.nodePrincipal ); }, raiseProvisioningFailure: function nsDOMIdentity_raiseProvisioningFailure(aReason) { @@ -393,17 +374,17 @@ nsDOMIdentity.prototype = { } 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( + this._mm.sendAsyncMessage( "Identity:IDP:ProvisioningFailure", message, null, this._window.document.nodePrincipal ); }, /** @@ -418,34 +399,34 @@ nsDOMIdentity.prototype = { 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( + this._mm.sendAsyncMessage( "Identity:IDP:BeginAuthentication", this.DOMIdentityMessage(), null, this._window.document.nodePrincipal ); }, 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( + this._mm.sendAsyncMessage( "Identity:IDP:CompleteAuthentication", this.DOMIdentityMessage(), null, this._window.document.nodePrincipal ); }, raiseAuthenticationFailure: function nsDOMIdentity_raiseAuthenticationFailure(aReason) { @@ -453,44 +434,24 @@ nsDOMIdentity.prototype = { 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( + this._mm.sendAsyncMessage( "Identity:IDP:AuthenticationFailure", message, null, this._window.document.nodePrincipal ); }, - // Private. - _init: function nsDOMIdentity__init(aWindow) { - - this._initializeState(); - - // Store window and origin URI. - this._window = aWindow; - this._origin = aWindow.document.nodePrincipal.origin; - this._appStatus = aWindow.document.nodePrincipal.appStatus; - this._appId = aWindow.document.nodePrincipal.appId; - - // Setup identifiers for current window. - let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - - // We need to inherit the id from the internalIdentity service. - // See comments below in that service's init. - this._id = this._identityInternal._id; - }, - /** * 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; @@ -498,22 +459,28 @@ nsDOMIdentity.prototype = { this._rpWatcher = null; this._onCancelRequestCallback = null; this._beginProvisioningCallback = null; this._genKeyPairCallback = null; this._beginAuthenticationCallback = null; }, - _receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) { + // nsIMessageListener + receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) { let msg = aMessage.json; + // Is this message intended for this window? + if (msg.id != this._id) { + return; + } + switch (aMessage.name) { case "Identity:ResetState": - if (!this._identityInternal._debug) { + if (!this._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) { @@ -581,20 +548,16 @@ nsDOMIdentity.prototype = { 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 @@ -671,98 +634,79 @@ nsDOMIdentity.prototype = { // Replace any audience supplied by the RP with one that has been sanitised message.audience = _audience; this._log("DOMIdentityMessage: " + JSON.stringify(message)); return message; }, - uninit: function DOMIdentity_uninit() { - this._log("nsDOMIdentity uninit() " + this._id); - this._identityInternal._mm.sendAsyncMessage( - "Identity:RP:Unwatch", - { id: this._id }, - null, - this._window.document.nodePrincipal - ); - } - -}; - -/** - * Internal functions that shouldn't be exposed to content. - */ -function nsDOMIdentityInternal() { -} -nsDOMIdentityInternal.prototype = { - - // nsIMessageListener - 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); - }, - + /** + * Internal methods that are not exposed to content. + * See dom/webidl/Identity.webidl for the public interface. + */ // nsIObserver observe: function nsDOMIdentityInternal_observe(aSubject, aTopic, aData) { let window = aSubject.QueryInterface(Ci.nsIDOMWindow); if (window != this._window) { return; } - this._identity.uninit(); + this.uninit(); Services.obs.removeObserver(this, "dom-window-destroyed"); - this._identity._initializeState(); - this._identity = null; + this._initializeState(); // 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 + // Because we implement nsIDOMGlobalPropertyInitializer, our init() method + // is invoked with content window as its single argument. 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); + // Setup identifiers for current window. let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); // To avoid cross-process windowId collisions, use a uuid as an // almost certainly unique identifier. // // XXX Bug 869182 - use a combination of child process id and // innerwindow id to construct the unique id. this._id = uuidgen.generateUUID().toString(); this._window = aWindow; // nsDOMIdentity needs to know our _id, so this goes after // its creation. - this._identity = new nsDOMIdentity(this); - this._identity._init(aWindow); + this._initializeState(); + + // Store window and origin URI. + this._window = aWindow; + this._origin = aWindow.document.nodePrincipal.origin; + this._appStatus = aWindow.document.nodePrincipal.appStatus; + this._appId = aWindow.document.nodePrincipal.appId; this._log("init was called from " + aWindow.document.location); this._mm = cpmm; // Setup listeners for messages from parent process. this._messages = [ "Identity:ResetState", @@ -776,34 +720,42 @@ nsDOMIdentityInternal.prototype = { "Identity:IDP:CallBeginAuthenticationCallback" ]; this._messages.forEach(function(msgName) { this._mm.addMessageListener(msgName, this); }, this); // Setup observers so we can remove message listeners. Services.obs.addObserver(this, "dom-window-destroyed", false); + }, - return this._identity; - }, + uninit: function DOMIdentity_uninit() { + this._log("nsDOMIdentity uninit() " + this._id); + this._mm.sendAsyncMessage( + "Identity:RP:Unwatch", + { id: this._id } + ); + }, // Private. _log: function nsDOMIdentityInternal__log(msg) { if (!this._debug) { return; } dump("nsDOMIdentity (" + this._id + "): " + msg + "\n"); }, // Component setup. classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"), - QueryInterface: XPCOMUtils.generateQI( - [Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIMessageListener] - ), + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsIMessageListener, + Ci.nsIObserver, + Ci.nsIDOMGlobalPropertyInitializer + ]), classInfo: XPCOMUtils.generateCI({ classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"), contractID: "@mozilla.org/dom/identity;1", interfaces: [], classDescription: "Identity DOM Implementation" }) }; @@ -835,9 +787,9 @@ function assertCorrectCallbacks(aOptions for (let cbName of optionalCallbacks) { if (aOptions[cbName] && typeof(aOptions[cbName]) != "function") { throw new Error(cbName + " must be a function"); } } } -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentityInternal]); +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentity]);
new file mode 100644 --- /dev/null +++ b/dom/webidl/Identity.webidl @@ -0,0 +1,70 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. + */ + +callback IdentityOnReadyCallback = void(); +callback IdentityOnLoginCallback = void(DOMString identityAssertion); +callback IdentityOnLogoutCallback = void(); +callback IdentityOnCancelCallback = void(DOMString? error); +callback IdentityOnErrorCallback = void(DOMString error); + +dictionary IdentityWatchOptions { + // Required callback + IdentityOnLoginCallback onlogin; + + // Optional parameters + DOMString wantIssuer; + DOMString loggedInUser; + + // Optional callbacks + IdentityOnReadyCallback onready; + IdentityOnLogoutCallback onlogout; + IdentityOnErrorCallback onerror; + + // Certified apps can specify this + DOMString audience; +}; + +dictionary IdentityRequestOptions { + // Optional parameters + long refreshAuthentication; + DOMString termsOfService; + DOMString privacyPolicy; + DOMString backgroundColor; + DOMString siteLogo; + DOMString siteName; + DOMString returnTo; + + IdentityOnCancelCallback oncancel; + + // Certified apps can specify this + DOMString origin; +}; + +dictionary IdentityGetOptions { + DOMString privacyPolicy; + DOMString termsOfService; + DOMString privacyURL; + DOMString tosURL; + DOMString siteName; + DOMString siteLogo; +}; + +[JSImplementation="@mozilla.org/identity/manager;1", + NoInterfaceObject, + NavigatorProperty="mozId", + Pref="dom.identity.enabled"] +interface IdentityManager { + void watch(optional IdentityWatchOptions options); + void request(optional IdentityRequestOptions options); + void logout(); + + [Pref="dom.identity.exposeLegacyGetAPI"] + void get(IdentityOnLoginCallback callback, optional IdentityGetOptions options); + + [Pref="dom.identity.exposeLegacyGetVerifiedEmailAPI"] + void getVerifiedEmail(IdentityOnLoginCallback callback); +}; +
--- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -227,16 +227,17 @@ WEBIDL_FILES = [ 'IDBIndex.webidl', 'IDBKeyRange.webidl', 'IDBMutableFile.webidl', 'IDBObjectStore.webidl', 'IDBOpenDBRequest.webidl', 'IDBRequest.webidl', 'IDBTransaction.webidl', 'IDBVersionChangeEvent.webidl', + 'Identity.webidl', 'ImageCapture.webidl', 'ImageData.webidl', 'ImageDocument.webidl', 'InputEvent.webidl', 'InputMethod.webidl', 'InspectorUtils.webidl', 'InstallEvent.webidl', 'InstallPhaseEvent.webidl',