MDN may have intermittent access issues April 18 13:00 - April 19 01:00 UTC. See whistlepig.mozilla.org for all notifications.

mozilla

Revision 136741 of Creating a Login Manager storage module

  • Revision slug: Creating_a_Login_Manager_storage_module
  • Revision title: Creating a Login Manager storage module
  • Revision id: 136741
  • Created:
  • Creator: Kohei
  • Is current revision? No
  • Comment Added ja

Revision Content

{{template.Fx_minversion_header(3)}} The Login Manager manages and stores user passwords. Extensions can replace the built-in password storage with their own implementation. This can be useful if you want to integrate Firefox password management with an existing password management system, or use your own password storage format or database.

If you just want to use the Login Manager in your extensions, refer to the article Using nsILoginManager.

Overriding the built-in Login Manager storage consists of two tasks:

  1. Implement the {{template.Interface("nsILoginManagerStorage")}} interface.
  2. Register that interface in a specific category.
Some work has already been done to integrate the Login Manager with the Mac OS X keychain ({{template.Bug(106400)}}) and Gnome Keyring Manager ({{template.Bug(309807)}}). You should start with the existing code if you want to implement that in your extension.

Sample JavaScript implementation

The following code snippet is a JavaScript component that implements a dummy {{template.Interface("nsILoginManagerStorage")}} interface. See How_to_Build_an_XPCOM_Component_in_Javascript for more details about JavaScript components.

const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function SampleLoginManagerStorage() {}
SampleLoginManagerStorage.prototype = {
  classDescription: "Sample nsILoginManagerStorage implementation",
  contractID: "@example.com/login-manager/storage/sample;1",
  classID: Components.ID("{364a118c-747a-4f6d-ac63-2d2998e5a5c1}"),
  QueryInterface: XPCOMUtils.generateQI([Ci.nsILoginManagerStorage]),

  // This registers the category for overriding the built-in nsILoginManagerStorage
  _xpcom_categories: [
    {
      category: "login-manager-storage",
      entry: "nsILoginManagerStorage"
    }
  ],
  

 // Console logging service, used for debugging.
  __logService : null,
  get _logService() {
    if (!this.__logService)
      this.__logService = Cc["@mozilla.org/consoleservice;1"].
                            getService(Ci.nsIConsoleService);
    return this.__logService;
  },
  log: function (message) {
    dump("SampleLoginManager: " + message + "\n");
    this._logService.logStringMessage("SampleLoginManager: " + message);
  },
  // Logs function name and arguments for debugging
  stub: function(arguments) {
    var args = [];
    for (let i = 0; i < arguments.length; i++)
      args.push(arguments[i])
    this.log("Called " + arguments.callee.name + "(" + args.join(",") + ")");
  },

  init: function SLMS_init() {
    this.stub(arguments);
  },
  initWithFile: function SLMS_initWithFile(aInputFile, aOutputFile) {
    this.stub(arguments);
  },
  addLogin: function SLMS_addLogin(login) {
    this.stub(arguments);
  },
  removeLogin: function SLMS_removeLogin(login) {
    this.stub(arguments);
  },
  modifyLogin: function SLMS_modifyLogin(oldLogin, newLogin) {
    this.stub(arguments);
  },
  getAllLogins: function SLMS_getAllLogins(count) {
    this.stub(arguments);
  },
  removeAllLogins: function SLMS_removeAllLogins() {
    this.stub(arguments);
  },
  getAllDisabledHosts: function SLMS_getAllDisabledHosts(count) {
    this.stub(arguments);
  },
  getLoginSavingEnabled: function SLMS_getLoginSavingEnabled(hostname) {
    this.stub(arguments);
  },
  setLoginSavingEnabled: function SLMS_setLoginSavingEnabled(hostname, enabled) {
    this.stub(arguments);
  },
  findLogins: function SLMS_findLogins(count, hostname, formSubmitURL, httpRealm) {
    this.stub(arguments);
  },
  countLogins: function SLMS_countLogins(aHostname, aFormSubmitURL, aHttpRealm) {
    this.stub(arguments);
  }
};

function NSGetModule(compMgr, fileSpec)
  XPCOMUtils.generateModule([SampleLoginManagerStorage]);

Sample C++ Implementation

{{template.Bug(309807)}} contains a complete example. The category registration looks like this:

  nsCOMPtr<nsICategoryManager> cat =
      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
  NS_ENSURE_STATE(cat);

  cat->AddCategoryEntry("login-manager-storage", "nsILoginManagerStorage",
                        kYourContractID, PR_TRUE, PR_TRUE, nsnull);

Don't forget to unregister the category on unload.

{{ wiki.languages( { "ja": "ja/Editing_Creating_a_Login_Manager_storage_module" } ) }}

Revision Source

<p>{{template.Fx_minversion_header(3)}}
The Login Manager manages and stores user passwords. Extensions can replace the built-in password storage with their own implementation. This can be useful if you want to integrate Firefox password management with an existing password management system, or use your own password storage format or database.
</p><p>If you just want to use the Login Manager in your extensions, refer to the article <a href="en/Using_nsILoginManager">Using nsILoginManager</a>.
</p><p>Overriding the built-in Login Manager storage consists of two tasks:
</p>
<ol><li> Implement the {{template.Interface("nsILoginManagerStorage")}} interface.
</li><li> Register that interface in a specific category.
</li></ol>
<div class="note">Some work has already been done to integrate the Login Manager with the Mac OS X keychain ({{template.Bug(106400)}}) and Gnome Keyring Manager ({{template.Bug(309807)}}). You should start with the existing code if you want to implement that in your extension.</div>
<h3 name="Sample_JavaScript_implementation"> Sample JavaScript implementation </h3>
<p>The following code snippet is a JavaScript component that implements a dummy {{template.Interface("nsILoginManagerStorage")}} interface. See <a href="en/How_to_Build_an_XPCOM_Component_in_Javascript">How_to_Build_an_XPCOM_Component_in_Javascript</a> for more details about JavaScript components.
</p>
<pre>const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function SampleLoginManagerStorage() {}
SampleLoginManagerStorage.prototype = {
  classDescription: "Sample nsILoginManagerStorage implementation",
  contractID: "@example.com/login-manager/storage/sample;1",
  classID: Components.ID("{364a118c-747a-4f6d-ac63-2d2998e5a5c1}"),
  QueryInterface: XPCOMUtils.generateQI([Ci.nsILoginManagerStorage]),

  // This registers the category for overriding the built-in nsILoginManagerStorage
  _xpcom_categories: [
    {
      category: "login-manager-storage",
      entry: "nsILoginManagerStorage"
    }
  ],
  

 // Console logging service, used for debugging.
  __logService : null,
  get _logService() {
    if (!this.__logService)
      this.__logService = Cc["@mozilla.org/consoleservice;1"].
                            getService(Ci.nsIConsoleService);
    return this.__logService;
  },
  log: function (message) {
    dump("SampleLoginManager: " + message + "\n");
    this._logService.logStringMessage("SampleLoginManager: " + message);
  },
  // Logs function name and arguments for debugging
  stub: function(arguments) {
    var args = [];
    for (let i = 0; i &lt; arguments.length; i++)
      args.push(arguments[i])
    this.log("Called " + arguments.callee.name + "(" + args.join(",") + ")");
  },

  init: function SLMS_init() {
    this.stub(arguments);
  },
  initWithFile: function SLMS_initWithFile(aInputFile, aOutputFile) {
    this.stub(arguments);
  },
  addLogin: function SLMS_addLogin(login) {
    this.stub(arguments);
  },
  removeLogin: function SLMS_removeLogin(login) {
    this.stub(arguments);
  },
  modifyLogin: function SLMS_modifyLogin(oldLogin, newLogin) {
    this.stub(arguments);
  },
  getAllLogins: function SLMS_getAllLogins(count) {
    this.stub(arguments);
  },
  removeAllLogins: function SLMS_removeAllLogins() {
    this.stub(arguments);
  },
  getAllDisabledHosts: function SLMS_getAllDisabledHosts(count) {
    this.stub(arguments);
  },
  getLoginSavingEnabled: function SLMS_getLoginSavingEnabled(hostname) {
    this.stub(arguments);
  },
  setLoginSavingEnabled: function SLMS_setLoginSavingEnabled(hostname, enabled) {
    this.stub(arguments);
  },
  findLogins: function SLMS_findLogins(count, hostname, formSubmitURL, httpRealm) {
    this.stub(arguments);
  },
  countLogins: function SLMS_countLogins(aHostname, aFormSubmitURL, aHttpRealm) {
    this.stub(arguments);
  }
};

function NSGetModule(compMgr, fileSpec)
  XPCOMUtils.generateModule([SampleLoginManagerStorage]);

</pre>
<h3 name="Sample_C.2B.2B_Implementation"> Sample C++ Implementation </h3>
<p>{{template.Bug(309807)}} contains a complete example. The category registration looks like this:
</p>
<pre>  nsCOMPtr&lt;nsICategoryManager&gt; cat =
      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
  NS_ENSURE_STATE(cat);

  cat-&gt;AddCategoryEntry("login-manager-storage", "nsILoginManagerStorage",
                        kYourContractID, PR_TRUE, PR_TRUE, nsnull);
</pre>
<p>Don't forget to unregister the category on unload.
</p>{{ wiki.languages( { "ja": "ja/Editing_Creating_a_Login_Manager_storage_module" } ) }}
Revert to this revision