GUACAMOLE-5: Display share links within Guacamole menu. Persist within ManagedClient.

This commit is contained in:
Michael Jumper
2016-08-02 13:08:04 -07:00
parent e1cf5821fc
commit 73c2e68922
6 changed files with 246 additions and 14 deletions

View File

@@ -28,7 +28,6 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
var ManagedClientState = $injector.get('ManagedClientState');
var ManagedFilesystem = $injector.get('ManagedFilesystem');
var ScrollState = $injector.get('ScrollState');
var UserCredentials = $injector.get('UserCredentials');
// Required services
var $location = $injector.get('$location');
@@ -435,26 +434,42 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
/**
* Produces a sharing link for the current connection using the given
* sharing profile. The resulting sharing link, and any required login
* information, will be displayed to the user once the various underlying
* service calls succeed.
* information, will be displayed to the user within the Guacamole menu.
*
* @param {SharingProfile} sharingProfile
* The sharing profile to use to generate the sharing link.
*/
$scope.share = function share(sharingProfile) {
ManagedClient.createShareLink($scope.client, sharingProfile);
};
// Retrieve sharing credentials for the sake of generating a share link
tunnelService.getSharingCredentials($scope.client.tunnel.uuid, sharingProfile.identifier)
.success(function sharingCredentialsReceived(sharingCredentials) {
/**
* Returns whether the current connection has any associated share links.
*
* @returns {Boolean}
* true if the current connection has at least one associated share
* link, false otherwise.
*/
$scope.isShared = function isShared() {
return ManagedClient.isShared($scope.client);
};
// TODONT: COMPLETE HACK: Shove the share link into the clipboard
var href = UserCredentials.getLink(sharingCredentials);
$scope.client.clipboardData = {
'type' : 'text/plain',
'data' : href
};
/**
* Returns the total number of share links associated with the current
* connection.
*
* @returns {Number}
* The total number of share links associated with the current
* connection.
*/
$scope.getShareLinkCount = function getShareLinkCount() {
});
// Count total number of links within the ManagedClient's share link map
var linkCount = 0;
for (var dummy in $scope.client.shareLinks)
linkCount++;
return linkCount;
};

View File

@@ -171,3 +171,31 @@
#guac-menu #devices .device.filesystem {
background-image: url('images/drive.png');
}
#guac-menu #share-links {
padding: 1em;
border: 1px solid rgba(0, 0, 0, 0.125);
background: rgba(0, 0, 0, 0.04);
font-size: 0.8em;
}
#guac-menu #share-links h3 {
padding-bottom: 0;
}
#guac-menu #share-links th {
white-space: nowrap;
}
#guac-menu #share-links a[href] {
display: block;
padding: 0 1em;
font-family: monospace;
font-weight: bold;
}

View File

@@ -44,7 +44,7 @@
<div class="header">
<h2>{{client.name}}</h2>
<div class="share-menu" ng-show="canShareConnection()">
<guac-menu title="'CLIENT.ACTION_SHARE' | translate">
<guac-menu menu-title="'CLIENT.ACTION_SHARE' | translate">
<ul ng-repeat="sharingProfile in sharingProfiles">
<li><a ng-click="share(sharingProfile)">{{sharingProfile.name}}</a></li>
</ul>
@@ -56,6 +56,22 @@
<!-- Scrollable body -->
<div class="menu-body" guac-touch-drag="menuDrag" guac-scroll="menu.scrollState">
<!-- Connection sharing -->
<div class="menu-section" id="share-links" ng-show="isShared()">
<div class="content">
<h3>{{'CLIENT.INFO_CONNECTION_SHARED' | translate}}</h3>
<p class="description"
translate="CLIENT.HELP_SHARE_LINK"
translate-values="{LINKS : getShareLinkCount()}"></p>
<table>
<tr ng-repeat="link in client.shareLinks | orderBy: name">
<th>{{link.name}}</th>
<td><a href="{{link.href}}" target="_blank">{{link.href}}</a></td>
</tr>
</table>
</div>
</div>
<!-- Clipboard -->
<div class="menu-section" id="clipboard-settings">
<h3>{{'CLIENT.SECTION_HEADER_CLIPBOARD' | translate}}</h3>

View File

@@ -31,6 +31,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
var ManagedDisplay = $injector.get('ManagedDisplay');
var ManagedFilesystem = $injector.get('ManagedFilesystem');
var ManagedFileUpload = $injector.get('ManagedFileUpload');
var ManagedShareLink = $injector.get('ManagedShareLink');
// Required services
var $document = $injector.get('$document');
@@ -125,6 +126,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
*/
this.filesystems = template.filesystems || [];
/**
* All available share links generated for the this ManagedClient via
* ManagedClient.createShareLink(). Each resulting share link is stored
* under the identifier of its corresponding SharingProfile.
*
* @type Object.<String, ManagedShareLink>
*/
this.shareLinks = template.shareLinks || {};
/**
* The current state of the Guacamole client (idle, connecting,
* connected, terminated with error, etc.).
@@ -585,6 +595,62 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
};
/**
* Produces a sharing link for the given ManagedClient using the given
* sharing profile. The resulting sharing link, and any required login
* information, can be retrieved from the <code>shareLinks</code> property
* of the given ManagedClient once the various underlying service calls
* succeed.
*
* @param {ManagedClient} client
* The ManagedClient which will be shared via the generated sharing
* link.
*
* @param {SharingProfile} sharingProfile
* The sharing profile to use to generate the sharing link.
*
* @returns {Promise}
* A Promise which is resolved once the sharing link has been
* successfully generated, and rejected if generating the link fails.
*/
ManagedClient.createShareLink = function createShareLink(client, sharingProfile) {
// Retrieve sharing credentials for the sake of generating a share link
var credentialRequest = tunnelService.getSharingCredentials(
client.tunnel.uuid, sharingProfile.identifier);
// Add a new share link once the credentials are ready
credentialRequest.success(function sharingCredentialsReceived(sharingCredentials) {
client.shareLinks[sharingProfile.identifier] =
ManagedShareLink.getInstance(sharingProfile, sharingCredentials);
});
return credentialRequest;
};
/**
* Returns whether the given ManagedClient is being shared. A ManagedClient
* is shared if it has any associated share links.
*
* @param {ManagedClient} client
* The ManagedClient to check.
*
* @returns {Boolean}
* true if the ManagedClient has at least one associated share link,
* false otherwise.
*/
ManagedClient.isShared = function isShared(client) {
// The connection is shared if at least one share link exists
for (var dummy in client.shareLinks)
return true;
// No share links currently exist
return false;
};
return ManagedClient;
}]);

View File

@@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Provides the ManagedShareLink class used by ManagedClient to represent
* generated connection sharing links.
*/
angular.module('client').factory('ManagedShareLink', ['$injector',
function defineManagedShareLink($injector) {
// Required types
var UserCredentials = $injector.get('UserCredentials');
/**
* Object which represents a link which can be used to gain access to an
* active Guacamole connection.
*
* @constructor
* @param {ManagedShareLink|Object} [template={}]
* The object whose properties should be copied within the new
* ManagedShareLink.
*/
var ManagedShareLink = function ManagedShareLink(template) {
// Use empty object by default
template = template || {};
/**
* The human-readable display name of this share link.
*
* @type String
*/
this.name = template.name;
/**
* The actual URL of the link which can be used to access the shared
* connection.
*
* @type String
*/
this.href = template.href;
/**
* The sharing profile which was used to generate the share link.
*
* @type SharingProfile
*/
this.sharingProfile = template.sharingProfile;
/**
* The credentials from which the share link was derived.
*
* @type UserCredentials
*/
this.sharingCredentials = template.sharingCredentials;
};
/**
* Creates a new ManagedShareLink from a set of UserCredentials and the
* SharingProfile which was used to generate those UserCredentials.
*
* @param {SharingProfile} sharingProfile
* The SharingProfile which was used, via the REST API, to generate the
* given UserCredentials.
*
* @param {UserCredentials} sharingCredentials
* The UserCredentials object returned by the REST API in response to a
* request to share a connection using the given SharingProfile.
*
* @return {ManagedShareLink}
* A new ManagedShareLink object can be used to access the connection
* shared via the given SharingProfile and resulting UserCredentials.
*/
ManagedShareLink.getInstance = function getInstance(sharingProfile, sharingCredentials) {
// Generate new share link using the given profile and credentials
return new ManagedShareLink({
'name' : sharingProfile.name,
'href' : UserCredentials.getLink(sharingCredentials),
'sharingProfile' : sharingProfile,
'sharingCredentials' : sharingCredentials
});
};
return ManagedShareLink;
}]);

View File

@@ -103,7 +103,9 @@
"HELP_MOUSE_MODE" : "Determines how the remote mouse behaves with respect to touches.",
"HELP_MOUSE_MODE_ABSOLUTE" : "Tap to click. The click occurs at the location of the touch.",
"HELP_MOUSE_MODE_RELATIVE" : "Drag to move the mouse pointer and tap to click. The click occurs at the location of the pointer.",
"HELP_SHARE_LINK" : "The current connection is being shared, and can be accessed by anyone with the following {LINKS, plural, one{link} other{links}}:",
"INFO_CONNECTION_SHARED" : "This connection is now shared.",
"INFO_NO_FILE_TRANSFERS" : "No file transfers.",
"NAME_INPUT_METHOD_NONE" : "None",