mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-09 06:31:22 +00:00
GUAC-586: Use data source when connecting to connections or groups. Remove deprecated getUserContext() from GuacamoleSession and related classes. Use identifiers which embed the data source for client URLs.
This commit is contained in:
@@ -158,7 +158,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
||||
var RECONNECT_ACTION = {
|
||||
name : "CLIENT.ACTION_RECONNECT",
|
||||
callback : function reconnectCallback() {
|
||||
$scope.client = guacClientManager.replaceManagedClient(uniqueId, $routeParams.params);
|
||||
$scope.client = guacClientManager.replaceManagedClient($routeParams.id, $routeParams.params);
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
@@ -219,13 +219,13 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
||||
$scope.$on('guacClientClipboard', function clientClipboardListener(event, client, mimetype, clipboardData) {
|
||||
$scope.clipboardData = clipboardData;
|
||||
});
|
||||
|
||||
/*
|
||||
* Parse the type, name, and id out of the url paramteres,
|
||||
* as well as any extra parameters if set.
|
||||
|
||||
/**
|
||||
* The client which should be attached to the client UI.
|
||||
*
|
||||
* @type ManagedClient
|
||||
*/
|
||||
var uniqueId = $routeParams.type + '/' + $routeParams.id;
|
||||
$scope.client = guacClientManager.getManagedClient(uniqueId, $routeParams.params);
|
||||
$scope.client = guacClientManager.getManagedClient($routeParams.id, $routeParams.params);
|
||||
|
||||
var keysCurrentlyPressed = {};
|
||||
|
||||
|
@@ -28,6 +28,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
|
||||
// Required types
|
||||
var ClientProperties = $injector.get('ClientProperties');
|
||||
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||
var ManagedClientState = $injector.get('ManagedClientState');
|
||||
var ManagedDisplay = $injector.get('ManagedDisplay');
|
||||
var ManagedFileDownload = $injector.get('ManagedFileDownload');
|
||||
@@ -153,8 +154,8 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
* desired connection ID, display resolution, and supported audio/video
|
||||
* codecs.
|
||||
*
|
||||
* @param {String} id
|
||||
* The ID of the connection or group to connect to.
|
||||
* @param {ClientIdentifier} identifier
|
||||
* The identifier representing the connection or group to connect to.
|
||||
*
|
||||
* @param {String} [connectionParameters]
|
||||
* Any additional HTTP parameters to pass while connecting.
|
||||
@@ -163,7 +164,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
* The string of connection parameters to be passed to the Guacamole
|
||||
* client.
|
||||
*/
|
||||
var getConnectString = function getConnectString(id, connectionParameters) {
|
||||
var getConnectString = function getConnectString(identifier, connectionParameters) {
|
||||
|
||||
// Calculate optimal width/height for display
|
||||
var pixel_density = $window.devicePixelRatio || 1;
|
||||
@@ -173,21 +174,23 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
|
||||
// Build base connect string
|
||||
var connectString =
|
||||
"id=" + encodeURIComponent(id)
|
||||
+ "&authToken=" + encodeURIComponent(authenticationService.getCurrentToken())
|
||||
+ "&width=" + Math.floor(optimal_width)
|
||||
+ "&height=" + Math.floor(optimal_height)
|
||||
+ "&dpi=" + Math.floor(optimal_dpi)
|
||||
"token=" + encodeURIComponent(authenticationService.getCurrentToken())
|
||||
+ "&GUAC_DATA_SOURCE=" + encodeURIComponent(identifier.dataSource)
|
||||
+ "&GUAC_ID=" + encodeURIComponent(identifier.id)
|
||||
+ "&GUAC_TYPE=" + encodeURIComponent(identifier.type)
|
||||
+ "&GUAC_WIDTH=" + Math.floor(optimal_width)
|
||||
+ "&GUAC_HEIGHT=" + Math.floor(optimal_height)
|
||||
+ "&GUAC_DPI=" + Math.floor(optimal_dpi)
|
||||
+ (connectionParameters ? '&' + connectionParameters : '');
|
||||
|
||||
// Add audio mimetypes to connect_string
|
||||
guacAudio.supported.forEach(function(mimetype) {
|
||||
connectString += "&audio=" + encodeURIComponent(mimetype);
|
||||
connectString += "&GUAC_AUDIO=" + encodeURIComponent(mimetype);
|
||||
});
|
||||
|
||||
// Add video mimetypes to connect_string
|
||||
guacVideo.supported.forEach(function(mimetype) {
|
||||
connectString += "&video=" + encodeURIComponent(mimetype);
|
||||
connectString += "&GUAC_VIDEO=" + encodeURIComponent(mimetype);
|
||||
});
|
||||
|
||||
return connectString;
|
||||
@@ -238,7 +241,9 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
* or group.
|
||||
*
|
||||
* @param {String} id
|
||||
* The ID of the connection or group to connect to.
|
||||
* The ID of the connection or group to connect to. This String must be
|
||||
* a valid ClientIdentifier string, as would be generated by
|
||||
* ClientIdentifier.toString().
|
||||
*
|
||||
* @param {String} [connectionParameters]
|
||||
* Any additional HTTP parameters to pass while connecting.
|
||||
@@ -402,23 +407,23 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
||||
// Manage the client display
|
||||
managedClient.managedDisplay = ManagedDisplay.getInstance(client.getDisplay());
|
||||
|
||||
// Connect the Guacamole client
|
||||
client.connect(getConnectString(id, connectionParameters));
|
||||
// Parse connection details from ID
|
||||
var clientIdentifier = ClientIdentifier.fromString(id);
|
||||
|
||||
// Determine type of connection
|
||||
var typePrefix = id.substring(0, 2);
|
||||
// Connect the Guacamole client
|
||||
client.connect(getConnectString(clientIdentifier, connectionParameters));
|
||||
|
||||
// If using a connection, pull connection name
|
||||
if (typePrefix === 'c/') {
|
||||
connectionService.getConnection(id.substring(2))
|
||||
if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION) {
|
||||
connectionService.getConnection(clientIdentifier.dataSource, clientIdentifier.id)
|
||||
.success(function connectionRetrieved(connection) {
|
||||
managedClient.name = connection.name;
|
||||
});
|
||||
}
|
||||
|
||||
// If using a connection group, pull connection name
|
||||
else if (typePrefix === 'g/') {
|
||||
connectionGroupService.getConnectionGroup(id.substring(2))
|
||||
else if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION_GROUP) {
|
||||
connectionGroupService.getConnectionGroup(clientIdentifier.dataSource, clientIdentifier.id)
|
||||
.success(function connectionGroupRetrieved(group) {
|
||||
managedClient.name = group.name;
|
||||
});
|
||||
|
@@ -27,7 +27,8 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
function homeController($scope, $injector) {
|
||||
|
||||
// Get required types
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||
|
||||
// Get required services
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
@@ -56,6 +57,51 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Object passed to the guacGroupList directive, providing context-specific
|
||||
* functions or data.
|
||||
*/
|
||||
$scope.context = {
|
||||
|
||||
/**
|
||||
* Returns the unique string identifier which must be used when
|
||||
* connecting to a connection or connection group represented by the
|
||||
* given GroupListItem.
|
||||
*
|
||||
* @param {GroupListItem} item
|
||||
* The GroupListItem to determine the client identifier of.
|
||||
*
|
||||
* @returns {String}
|
||||
* The client identifier associated with the connection or
|
||||
* connection group represented by the given GroupListItem, or null
|
||||
* if the GroupListItem cannot have an associated client
|
||||
* identifier.
|
||||
*/
|
||||
getClientIdentifier : function getClientIdentifier(item) {
|
||||
|
||||
// If the item is a connection, generate a connection identifier
|
||||
if (item.isConnection)
|
||||
return ClientIdentifier.toString({
|
||||
dataSource : item.dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION,
|
||||
id : item.identifier
|
||||
});
|
||||
|
||||
// If the item is a connection, generate a connection group identifier
|
||||
if (item.isConnectionGroup)
|
||||
return ClientIdentifier.toString({
|
||||
dataSource : item.dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||
id : item.identifier
|
||||
});
|
||||
|
||||
// Otherwise, no such identifier can exist
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Retrieve root groups and all descendants
|
||||
dataSourceService.apply(
|
||||
connectionGroupService.getConnectionGroupTree,
|
||||
|
@@ -48,6 +48,7 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
||||
|
||||
// Required types
|
||||
var ActiveConnection = $injector.get('ActiveConnection');
|
||||
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||
var RecentConnection = $injector.get('RecentConnection');
|
||||
|
||||
// Required services
|
||||
@@ -104,7 +105,11 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
||||
var addVisibleConnection = function addVisibleConnection(dataSource, connection) {
|
||||
|
||||
// Add given connection to set of visible objects
|
||||
visibleObjects['c/' + connection.identifier] = connection;
|
||||
visibleObjects[ClientIdentifier.toString({
|
||||
dataSource : dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION,
|
||||
id : connection.identifier
|
||||
})] = connection;
|
||||
|
||||
};
|
||||
|
||||
@@ -123,7 +128,11 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
||||
var addVisibleConnectionGroup = function addVisibleConnectionGroup(dataSource, connectionGroup) {
|
||||
|
||||
// Add given connection group to set of visible objects
|
||||
visibleObjects['g/' + connectionGroup.identifier] = connectionGroup;
|
||||
visibleObjects[ClientIdentifier.toString({
|
||||
dataSource : dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||
id : connectionGroup.identifier
|
||||
})] = connectionGroup;
|
||||
|
||||
// Add all child connections
|
||||
if (connectionGroup.childConnections)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<a ng-href="#/client/c/{{item.identifier}}">
|
||||
<a ng-href="#/client/{{context.getClientIdentifier(item)}}">
|
||||
<!--
|
||||
Copyright (C) 2014 Glyptodon LLC
|
||||
|
||||
|
@@ -21,6 +21,6 @@
|
||||
THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<a ng-show="item.isBalancing" ng-href="#/client/g/{{item.identifier}}">{{item.name}}</a>
|
||||
<a ng-show="item.isBalancing" ng-href="#/client/{{context.getClientIdentifier(item)}}">{{item.name}}</a>
|
||||
<span ng-show="!item.isBalancing">{{item.name}}</span>
|
||||
</span>
|
||||
|
@@ -37,6 +37,7 @@
|
||||
<h2 class="header">{{'HOME.SECTION_HEADER_ALL_CONNECTIONS' | translate}}</h2>
|
||||
<div class="all-connections">
|
||||
<guac-group-list
|
||||
context="context"
|
||||
connection-groups="rootConnectionGroups"
|
||||
connection-template="'app/home/templates/connection.html'"
|
||||
connection-group-template="'app/home/templates/connectionGroup.html'"
|
||||
|
@@ -159,7 +159,7 @@ angular.module('index').config(['$routeProvider', '$locationProvider',
|
||||
})
|
||||
|
||||
// Client view
|
||||
.when('/client/:type/:id/:params?', {
|
||||
.when('/client/:id/:params?', {
|
||||
bodyClassName : 'client',
|
||||
templateUrl : 'app/client/templates/client.html',
|
||||
controller : 'clientController',
|
||||
|
@@ -23,4 +23,8 @@
|
||||
/**
|
||||
* Module for generating and implementing user navigation options.
|
||||
*/
|
||||
angular.module('navigation', ['notification', 'rest']);
|
||||
angular.module('navigation', [
|
||||
'auth',
|
||||
'notification',
|
||||
'rest'
|
||||
]);
|
||||
|
@@ -27,9 +27,10 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
function userPageService($injector) {
|
||||
|
||||
// Get required types
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var PageDefinition = $injector.get('PageDefinition');
|
||||
var PermissionSet = $injector.get('PermissionSet');
|
||||
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var PageDefinition = $injector.get('PageDefinition');
|
||||
var PermissionSet = $injector.get('PermissionSet');
|
||||
|
||||
// Get required services
|
||||
var $q = $injector.get('$q');
|
||||
@@ -102,7 +103,11 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
if (connection) {
|
||||
homePage = new PageDefinition(
|
||||
connection.name,
|
||||
'/client/c/' + encodeURIComponent(connection.identifier)
|
||||
'/client/' + ClientIdentifier.toString({
|
||||
dataSource : dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION,
|
||||
id : connection.identifier
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,7 +118,11 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
&& _.isEmpty(connectionGroup.childConnectionGroups)) {
|
||||
homePage = new PageDefinition(
|
||||
connectionGroup.name,
|
||||
'/client/g/' + encodeURIComponent(connectionGroup.identifier)
|
||||
'/client/' + ClientIdentifier.toString({
|
||||
dataSource : dataSource,
|
||||
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||
id : connectionGroup.identifier
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides the ClientIdentifier class definition.
|
||||
*/
|
||||
angular.module('client').factory('ClientIdentifier', ['$injector',
|
||||
function defineClientIdentifier($injector) {
|
||||
|
||||
// Required services
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var $window = $injector.get('$window');
|
||||
|
||||
/**
|
||||
* Object which uniquely identifies a particular connection or connection
|
||||
* group within Guacamole. This object can be converted to/from a string to
|
||||
* generate a guaranteed-unique, deterministic identifier for client URLs.
|
||||
*
|
||||
* @constructor
|
||||
* @param {ClientIdentifier|Object} [template={}]
|
||||
* The object whose properties should be copied within the new
|
||||
* ClientIdentifier.
|
||||
*/
|
||||
var ClientIdentifier = function ClientIdentifier(template) {
|
||||
|
||||
// Use empty object by default
|
||||
template = template || {};
|
||||
|
||||
/**
|
||||
* The identifier of the data source associated with the object to
|
||||
* which the client will connect. This identifier will be the
|
||||
* identifier of an AuthenticationProvider within the Guacamole web
|
||||
* application.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
this.dataSource = template.dataSource;
|
||||
|
||||
/**
|
||||
* The type of object to which the client will connect. Possible values
|
||||
* are defined within ClientIdentifier.Types.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
this.type = template.type;
|
||||
|
||||
/**
|
||||
* The unique identifier of the object to which the client will
|
||||
* connect.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
this.id = template.id;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* All possible ClientIdentifier types.
|
||||
*
|
||||
* @type Object.<String, String>
|
||||
*/
|
||||
ClientIdentifier.Types = {
|
||||
|
||||
/**
|
||||
* The type string for a Guacamole connection.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
CONNECTION : 'c',
|
||||
|
||||
/**
|
||||
* The type string for a Guacamole connection group.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
CONNECTION_GROUP : 'g'
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the given ClientIdentifier or ClientIdentifier-like object to
|
||||
* a String representation. Any object having the same properties as
|
||||
* ClientIdentifier may be used, but only those properties will be taken
|
||||
* into account when producing the resulting String.
|
||||
*
|
||||
* @param {ClientIdentifier|Object} id
|
||||
* The ClientIdentifier or ClientIdentifier-like object to convert to
|
||||
* a String representation.
|
||||
*
|
||||
* @returns {String}
|
||||
* A deterministic String representation of the given ClientIdentifier
|
||||
* or ClientIdentifier-like object.
|
||||
*/
|
||||
ClientIdentifier.toString = function toString(id) {
|
||||
return $window.btoa([
|
||||
id.id,
|
||||
id.type,
|
||||
id.dataSource
|
||||
].join('\0'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the given String into the corresponding ClientIdentifier. If
|
||||
* the provided String is not a valid identifier, it will be interpreted
|
||||
* as the identifier of a connection within the data source that
|
||||
* authenticated the current user.
|
||||
*
|
||||
* @param {String} str
|
||||
* The String to convert to a ClientIdentifier.
|
||||
*
|
||||
* @returns {ClientIdentifier}
|
||||
* The ClientIdentifier represented by the given String.
|
||||
*/
|
||||
ClientIdentifier.fromString = function fromString(str) {
|
||||
|
||||
try {
|
||||
var values = $window.atob(str).split('\0');
|
||||
return new ClientIdentifier({
|
||||
id : values[0],
|
||||
type : values[1],
|
||||
dataSource : values[2]
|
||||
});
|
||||
}
|
||||
|
||||
// If the provided string is invalid, transform into a reasonable guess
|
||||
catch (e) {
|
||||
return new ClientIdentifier({
|
||||
id : str,
|
||||
type : ClientIdentifier.Types.CONNECTION,
|
||||
dataSource : authenticationService.getDataSource() || 'default'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return ClientIdentifier;
|
||||
|
||||
}]);
|
Reference in New Issue
Block a user