Javascript  |  108行  |  3.56 KB

// Copyright 2013 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.

/**
 * @fileoverview
 * Obtains additional host permissions, showing a consent dialog if needed.
 *
 * When third party authentication is being used, the client must talk to a
 * third-party server. For that, once the URL is received from the host the
 * webapp must use Chrome's optional permissions API to check if it has the
 * "host" permission needed to access that URL. If the webapp hasn't already
 * been granted that permission, it shows a dialog explaining why it is being
 * requested, then uses the Chrome API ask the user for the new permission.
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/**
 * @constructor
 * Encapsulates the UI to check/request permissions to a new host.
 *
 * @param {string} url The URL to request permission for.
 */
remoting.ThirdPartyHostPermissions = function(url) {
  this.url_ = url;
  this.permissions_ = {'origins': [url]};
};

/**
 * Get permissions to the URL, asking interactively if necessary.
 *
 * @param {function(): void} onOk Called if the permission is granted.
 * @param {function(): void} onError Called if the permission is denied.
 */
remoting.ThirdPartyHostPermissions.prototype.getPermission = function(
    onOk, onError) {
  /** @type {remoting.ThirdPartyHostPermissions} */
  var that = this;
  chrome.permissions.contains(this.permissions_,
    /** @param {boolean} allowed Whether this extension has this permission. */
    function(allowed) {
      if (allowed) {
        onOk();
      } else {
        // Optional permissions must be requested in a user action context. This
        // is called from an asynchronous plugin callback, so we have to open a
        // confirmation dialog to perform the request on an interactive event.
        // In any case, we can use this dialog to explain to the user why we are
        // asking for the additional permission.
        that.showPermissionConfirmation_(onOk, onError);
      }
    });
};

/**
 * Show an interactive dialog informing the user of the new permissions.
 *
 * @param {function(): void} onOk Called if the permission is granted.
 * @param {function(): void} onError Called if the permission is denied.
 * @private
 */
remoting.ThirdPartyHostPermissions.prototype.showPermissionConfirmation_ =
    function(onOk, onError) {
  /** @type {HTMLElement} */
  var button = document.getElementById('third-party-auth-button');
  /** @type {HTMLElement} */
  var url = document.getElementById('third-party-auth-url');
  url.innerText = this.url_;

  /** @type {remoting.ThirdPartyHostPermissions} */
  var that = this;

  var consentGranted = function(event) {
    remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
    button.removeEventListener('click', consentGranted, false);
    that.requestPermission_(onOk, onError);
  };

  button.addEventListener('click', consentGranted, false);
  remoting.setMode(remoting.AppMode.CLIENT_THIRD_PARTY_AUTH);
};


/**
 * Request permission from the user to access the token-issue URL.
 *
 * @param {function(): void} onOk Called if the permission is granted.
 * @param {function(): void} onError Called if the permission is denied.
 * @private
 */
remoting.ThirdPartyHostPermissions.prototype.requestPermission_ = function(
    onOk, onError) {
  chrome.permissions.request(
    this.permissions_,
    /** @param {boolean} result Whether the permission was granted. */
    function(result) {
      if (result) {
        onOk();
      } else {
        onError();
      }
  });
};