Home | History | Annotate | Download | only in webapp
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * @fileoverview
      7  * Obtains additional host permissions, showing a consent dialog if needed.
      8  *
      9  * When third party authentication is being used, the client must talk to a
     10  * third-party server. For that, once the URL is received from the host the
     11  * webapp must use Chrome's optional permissions API to check if it has the
     12  * "host" permission needed to access that URL. If the webapp hasn't already
     13  * been granted that permission, it shows a dialog explaining why it is being
     14  * requested, then uses the Chrome API ask the user for the new permission.
     15  */
     16 
     17 'use strict';
     18 
     19 /** @suppress {duplicate} */
     20 var remoting = remoting || {};
     21 
     22 /**
     23  * @constructor
     24  * Encapsulates the UI to check/request permissions to a new host.
     25  *
     26  * @param {string} url The URL to request permission for.
     27  */
     28 remoting.ThirdPartyHostPermissions = function(url) {
     29   this.url_ = url;
     30   this.permissions_ = {'origins': [url]};
     31 };
     32 
     33 /**
     34  * Get permissions to the URL, asking interactively if necessary.
     35  *
     36  * @param {function(): void} onOk Called if the permission is granted.
     37  * @param {function(): void} onError Called if the permission is denied.
     38  */
     39 remoting.ThirdPartyHostPermissions.prototype.getPermission = function(
     40     onOk, onError) {
     41   /** @type {remoting.ThirdPartyHostPermissions} */
     42   var that = this;
     43   chrome.permissions.contains(this.permissions_,
     44     /** @param {boolean} allowed Whether this extension has this permission. */
     45     function(allowed) {
     46       if (allowed) {
     47         onOk();
     48       } else {
     49         // Optional permissions must be requested in a user action context. This
     50         // is called from an asynchronous plugin callback, so we have to open a
     51         // confirmation dialog to perform the request on an interactive event.
     52         // In any case, we can use this dialog to explain to the user why we are
     53         // asking for the additional permission.
     54         that.showPermissionConfirmation_(onOk, onError);
     55       }
     56     });
     57 };
     58 
     59 /**
     60  * Show an interactive dialog informing the user of the new permissions.
     61  *
     62  * @param {function(): void} onOk Called if the permission is granted.
     63  * @param {function(): void} onError Called if the permission is denied.
     64  * @private
     65  */
     66 remoting.ThirdPartyHostPermissions.prototype.showPermissionConfirmation_ =
     67     function(onOk, onError) {
     68   /** @type {HTMLElement} */
     69   var button = document.getElementById('third-party-auth-button');
     70   /** @type {HTMLElement} */
     71   var url = document.getElementById('third-party-auth-url');
     72   url.innerText = this.url_;
     73 
     74   /** @type {remoting.ThirdPartyHostPermissions} */
     75   var that = this;
     76 
     77   var consentGranted = function(event) {
     78     remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
     79     button.removeEventListener('click', consentGranted, false);
     80     that.requestPermission_(onOk, onError);
     81   };
     82 
     83   button.addEventListener('click', consentGranted, false);
     84   remoting.setMode(remoting.AppMode.CLIENT_THIRD_PARTY_AUTH);
     85 };
     86 
     87 
     88 /**
     89  * Request permission from the user to access the token-issue URL.
     90  *
     91  * @param {function(): void} onOk Called if the permission is granted.
     92  * @param {function(): void} onError Called if the permission is denied.
     93  * @private
     94  */
     95 remoting.ThirdPartyHostPermissions.prototype.requestPermission_ = function(
     96     onOk, onError) {
     97   chrome.permissions.request(
     98     this.permissions_,
     99     /** @param {boolean} result Whether the permission was granted. */
    100     function(result) {
    101       if (result) {
    102         onOk();
    103       } else {
    104         onError();
    105       }
    106   });
    107 };
    108