| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| var binding = require('binding').Binding.create('certificateProvider'); |
| var certificateProviderInternal = require('binding').Binding.create( |
| 'certificateProviderInternal').generate(); |
| var eventBindings = require('event_bindings'); |
| |
| var certificateProviderSchema = |
| requireNative('schema_registry').GetSchema('certificateProvider') |
| var utils = require('utils'); |
| var validate = require('schemaUtils').validate; |
| |
| // Custom bindings for chrome.certificateProvider API. |
| // The bindings are used to implement callbacks for the API events. Internally |
| // each event is passed a requestId argument used to identify the callback |
| // associated with the event. This argument is massaged out from the event |
| // arguments before dispatching the event to consumers. A callback is appended |
| // to the event arguments. The callback wraps an appropriate |
| // chrome.certificateProviderInternal API function that is used to report the |
| // event result from the extension. The function is passed the requestId and |
| // values provided by the extension. It validates that the values provided by |
| // the extension match chrome.certificateProvider event callback schemas. It |
| // also ensures that a callback is run at most once. In case there is an |
| // exception during event dispatching, the chrome.certificateProviderInternal |
| // function is called with a default error value. |
| |
| // Handles a chrome.certificateProvider event as described in the file comment. |
| // |eventName|: The event name. The first argument of the event must be a |
| // request id. |
| // |internalReportFunc|: The function that should be called to report results in |
| // reply to an event. The first argument of the function must be the request |
| // id that was received with the event. |
| function handleEvent(eventName, internalReportFunc) { |
| var eventSchema = |
| utils.lookup(certificateProviderSchema.events, 'name', eventName); |
| var callbackSchema = utils.lookup(eventSchema.parameters, 'type', 'function'); |
| |
| eventBindings.registerArgumentMassager( |
| 'certificateProvider.' + eventName, |
| function(args, dispatch) { |
| var responded = false; |
| |
| // Function provided to the extension as the event callback argument. |
| // The extension calls this to report results in reply to the event. |
| // It throws an exception if called more than once and if the provided |
| // results don't match the callback schema. |
| var reportFunc = function(reportArg1, reportArg2) { |
| if (responded) { |
| throw new Error( |
| 'Event callback must not be called more than once.'); |
| } |
| |
| var reportArgs = [reportArg1]; |
| if (reportArg2 !== undefined) |
| reportArgs.push(reportArg2); |
| var finalArgs = []; |
| try { |
| // Validates that the results reported by the extension matche the |
| // callback schema of the event. Throws an exception in case of an |
| // error. |
| validate(reportArgs, callbackSchema.parameters); |
| finalArgs = reportArgs; |
| } finally { |
| responded = true; |
| internalReportFunc.apply( |
| null, [args[0] /* requestId */].concat(finalArgs)); |
| } |
| }; |
| dispatch(args.slice(1).concat(reportFunc)); |
| }); |
| } |
| |
| handleEvent('onCertificatesRequested', |
| certificateProviderInternal.reportCertificates); |
| |
| handleEvent('onSignDigestRequested', |
| certificateProviderInternal.reportSignature); |
| |
| exports.$set('binding', binding.generate()); |