toolkit/identity/MinimalIdentity.jsm

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.

     1 /* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
     2 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8  * This alternate implementation of IdentityService provides just the
     9  * channels for navigator.id, leaving the certificate storage to a
    10  * server-provided app.
    11  *
    12  * On b2g, the messages identity-controller-watch, -request, and
    13  * -logout, are observed by the component SignInToWebsite.jsm.
    14  */
    16 "use strict";
    18 this.EXPORTED_SYMBOLS = ["IdentityService"];
    20 const Cu = Components.utils;
    21 const Ci = Components.interfaces;
    22 const Cc = Components.classes;
    23 const Cr = Components.results;
    25 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    26 Cu.import("resource://gre/modules/Services.jsm");
    27 Cu.import("resource://gre/modules/identity/LogUtils.jsm");
    29 XPCOMUtils.defineLazyModuleGetter(this, "objectCopy",
    30                                   "resource://gre/modules/identity/IdentityUtils.jsm");
    32 XPCOMUtils.defineLazyModuleGetter(this, "makeMessageObject",
    33                                   "resource://gre/modules/identity/IdentityUtils.jsm");
    35 function log(...aMessageArgs) {
    36   Logger.log.apply(Logger, ["minimal core"].concat(aMessageArgs));
    37 }
    38 function reportError(...aMessageArgs) {
    39   Logger.reportError.apply(Logger, ["core"].concat(aMessageArgs));
    40 }
    42 function IDService() {
    43   Services.obs.addObserver(this, "quit-application-granted", false);
    45   // simplify, it's one object
    46   this.RP = this;
    47   this.IDP = this;
    49   // keep track of flows
    50   this._rpFlows = {};
    51   this._authFlows = {};
    52   this._provFlows = {};
    53 }
    55 IDService.prototype = {
    56   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
    58   observe: function observe(aSubject, aTopic, aData) {
    59     switch (aTopic) {
    60       case "quit-application-granted":
    61         this.shutdown();
    62         break;
    63     }
    64   },
    66   shutdown: function() {
    67     Services.obs.removeObserver(this, "quit-application-granted");
    68   },
    70   /**
    71    * Parse an email into username and domain if it is valid, else return null
    72    */
    73   parseEmail: function parseEmail(email) {
    74     var match = email.match(/^([^@]+)@([^@^/]+.[a-z]+)$/);
    75     if (match) {
    76       return {
    77         username: match[1],
    78         domain: match[2]
    79       };
    80     }
    81     return null;
    82   },
    84   /**
    85    * Register a listener for a given windowID as a result of a call to
    86    * navigator.id.watch().
    87    *
    88    * @param aCaller
    89    *        (Object)  an object that represents the caller document, and
    90    *                  is expected to have properties:
    91    *                  - id (unique, e.g. uuid)
    92    *                  - loggedInUser (string or null)
    93    *                  - origin (string)
    94    *
    95    *                  and a bunch of callbacks
    96    *                  - doReady()
    97    *                  - doLogin()
    98    *                  - doLogout()
    99    *                  - doError()
   100    *                  - doCancel()
   101    *
   102    */
   103   watch: function watch(aRpCaller) {
   104     // store the caller structure and notify the UI observers
   105     this._rpFlows[aRpCaller.id] = aRpCaller;
   107     log("flows:", Object.keys(this._rpFlows).join(', '));
   109     let options = makeMessageObject(aRpCaller);
   110     log("sending identity-controller-watch:", options);
   111     Services.obs.notifyObservers({wrappedJSObject: options},"identity-controller-watch", null);
   112   },
   114   /*
   115    * The RP has gone away; remove handles to the hidden iframe.
   116    * It's probable that the frame will already have been cleaned up.
   117    */
   118   unwatch: function unwatch(aRpId, aTargetMM) {
   119     let rp = this._rpFlows[aRpId];
   120     if (!rp) {
   121       return;
   122     }
   124     let options = makeMessageObject({
   125       id: aRpId,
   126       origin: rp.origin,
   127       messageManager: aTargetMM
   128     });
   129     log("sending identity-controller-unwatch for id", options.id, options.origin);
   130     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-unwatch", null);
   132     // Stop sending messages to this window
   133     delete this._rpFlows[aRpId];
   134   },
   136   /**
   137    * Initiate a login with user interaction as a result of a call to
   138    * navigator.id.request().
   139    *
   140    * @param aRPId
   141    *        (integer)  the id of the doc object obtained in .watch()
   142    *
   143    * @param aOptions
   144    *        (Object)  options including privacyPolicy, termsOfService
   145    */
   146   request: function request(aRPId, aOptions) {
   147     let rp = this._rpFlows[aRPId];
   148     if (!rp) {
   149       reportError("request() called before watch()");
   150       return;
   151     }
   153     // Notify UX to display identity picker.
   154     // Pass the doc id to UX so it can pass it back to us later.
   155     let options = makeMessageObject(rp);
   156     objectCopy(aOptions, options);
   157     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-request", null);
   158   },
   160   /**
   161    * Invoked when a user wishes to logout of a site (for instance, when clicking
   162    * on an in-content logout button).
   163    *
   164    * @param aRpCallerId
   165    *        (integer)  the id of the doc object obtained in .watch()
   166    *
   167    */
   168   logout: function logout(aRpCallerId) {
   169     let rp = this._rpFlows[aRpCallerId];
   170     if (!rp) {
   171       reportError("logout() called before watch()");
   172       return;
   173     }
   175     let options = makeMessageObject(rp);
   176     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-logout", null);
   177   },
   179   childProcessShutdown: function childProcessShutdown(messageManager) {
   180     Object.keys(this._rpFlows).forEach(function(key) {
   181       if (this._rpFlows[key]._mm === messageManager) {
   182         log("child process shutdown for rp", key, "- deleting flow");
   183         delete this._rpFlows[key];
   184       }
   185     }, this);
   186   },
   188   /*
   189    * once the UI-and-display-logic components have received
   190    * notifications, they call back with direct invocation of the
   191    * following functions (doLogin, doLogout, or doReady)
   192    */
   194   doLogin: function doLogin(aRpCallerId, aAssertion, aInternalParams) {
   195     let rp = this._rpFlows[aRpCallerId];
   196     if (!rp) {
   197       log("WARNING: doLogin found no rp to go with callerId " + aRpCallerId);
   198       return;
   199     }
   201     rp.doLogin(aAssertion, aInternalParams);
   202   },
   204   doLogout: function doLogout(aRpCallerId) {
   205     let rp = this._rpFlows[aRpCallerId];
   206     if (!rp) {
   207       log("WARNING: doLogout found no rp to go with callerId " + aRpCallerId);
   208       return;
   209     }
   211     // Logout from every site with the same origin
   212     let origin = rp.origin;
   213     Object.keys(this._rpFlows).forEach(function(key) {
   214       let rp = this._rpFlows[key];
   215       if (rp.origin === origin) {
   216         rp.doLogout();
   217       }
   218     }.bind(this));
   219   },
   221   doReady: function doReady(aRpCallerId) {
   222     let rp = this._rpFlows[aRpCallerId];
   223     if (!rp) {
   224       log("WARNING: doReady found no rp to go with callerId " + aRpCallerId);
   225       return;
   226     }
   228     rp.doReady();
   229   },
   231   doCancel: function doCancel(aRpCallerId) {
   232     let rp = this._rpFlows[aRpCallerId];
   233     if (!rp) {
   234       log("WARNING: doCancel found no rp to go with callerId " + aRpCallerId);
   235       return;
   236     }
   238     rp.doCancel();
   239   }
   240 };
   242 this.IdentityService = new IDService();

mercurial