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} */ 20var 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 */ 28remoting.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 */ 39remoting.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 */ 66remoting.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 */ 95remoting.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