From ddd144fc47c0ca344a7fab2f00d57348dd66a4e2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 2 Sep 2015 16:09:29 -0700 Subject: [PATCH] GUAC-586: Add support for data sources to connection and connection group management. --- .../app/index/config/indexRouteConfig.js | 6 +- .../controllers/manageConnectionController.js | 54 ++++++++++++------ .../manageConnectionGroupController.js | 34 +++++++---- .../navigation/services/userPageService.js | 57 +++++++++++-------- .../directives/guacSettingsConnections.js | 57 +++++++++++++------ .../app/settings/templates/connection.html | 2 +- .../settings/templates/connectionGroup.html | 2 +- .../templates/settingsConnections.html | 6 +- 8 files changed, 139 insertions(+), 79 deletions(-) diff --git a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js index f0a7f97f6..39808ea22 100644 --- a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js +++ b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js @@ -123,7 +123,7 @@ angular.module('index').config(['$routeProvider', '$locationProvider', }) // Management screen - .when('/settings/:tab', { + .when('/settings/:dataSource?/:tab', { title : 'APP.NAME', bodyClassName : 'settings', templateUrl : 'app/settings/templates/settings.html', @@ -132,7 +132,7 @@ angular.module('index').config(['$routeProvider', '$locationProvider', }) // Connection editor - .when('/manage/connections/:id?', { + .when('/manage/:dataSource/connections/:id?', { title : 'APP.NAME', bodyClassName : 'manage', templateUrl : 'app/manage/templates/manageConnection.html', @@ -141,7 +141,7 @@ angular.module('index').config(['$routeProvider', '$locationProvider', }) // Connection group editor - .when('/manage/connectionGroups/:id?', { + .when('/manage/:dataSource/connectionGroups/:id?', { title : 'APP.NAME', bodyClassName : 'manage', templateUrl : 'app/manage/templates/manageConnectionGroup.html', diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js index 04e1066d4..1f1dc5ab5 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js @@ -55,7 +55,15 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i guacNotification.showStatus(false); } }; - + + /** + * The unique identifier of the data source containing the connection being + * edited. + * + * @type String + */ + var dataSource = $routeParams.dataSource; + /** * The identifier of the original connection from which this connection is * being cloned. Only valid if this is a new connection. @@ -178,20 +186,24 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i }; // Pull connection attribute schema - schemaService.getConnectionAttributes().success(function attributesReceived(attributes) { + schemaService.getConnectionAttributes(dataSource) + .success(function attributesReceived(attributes) { $scope.attributes = attributes; }); // Pull connection group hierarchy - connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, - [PermissionSet.ObjectPermissionType.ADMINISTER]) + connectionGroupService.getConnectionGroupTree( + dataSource, + ConnectionGroup.ROOT_IDENTIFIER, + [PermissionSet.ObjectPermissionType.ADMINISTER] + ) .success(function connectionGroupReceived(rootGroup) { $scope.rootGroup = rootGroup; }); // Query the user's permissions for the current connection - permissionService.getPermissions(authenticationService.getCurrentUsername()) - .success(function permissionsReceived(permissions) { + permissionService.getPermissions(dataSource, authenticationService.getCurrentUsername()) + .success(function permissionsReceived(permissions) { $scope.permissions = permissions; @@ -220,7 +232,8 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i }); // Get protocol metadata - schemaService.getProtocols().success(function protocolsReceived(protocols) { + schemaService.getProtocols(dataSource) + .success(function protocolsReceived(protocols) { $scope.protocols = protocols; }); @@ -233,12 +246,14 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i if (identifier) { // Pull data from existing connection - connectionService.getConnection(identifier).success(function connectionRetrieved(connection) { + connectionService.getConnection(dataSource, identifier) + .success(function connectionRetrieved(connection) { $scope.connection = connection; }); // Pull connection history - connectionService.getConnectionHistory(identifier).success(function historyReceived(historyEntries) { + connectionService.getConnectionHistory(dataSource, identifier) + .success(function historyReceived(historyEntries) { // Wrap all history entries for sake of display $scope.historyEntryWrappers = []; @@ -249,7 +264,8 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i }); // Pull connection parameters - connectionService.getConnectionParameters(identifier).success(function parametersReceived(parameters) { + connectionService.getConnectionParameters(dataSource, identifier) + .success(function parametersReceived(parameters) { $scope.parameters = parameters; }); } @@ -258,7 +274,8 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i else if (cloneSourceIdentifier) { // Pull data from cloned connection - connectionService.getConnection(cloneSourceIdentifier).success(function connectionRetrieved(connection) { + connectionService.getConnection(dataSource, cloneSourceIdentifier) + .success(function connectionRetrieved(connection) { $scope.connection = connection; // Clear the identifier field because this connection is new @@ -269,7 +286,8 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i $scope.historyEntryWrappers = []; // Pull connection parameters from cloned connection - connectionService.getConnectionParameters(cloneSourceIdentifier).success(function parametersReceived(parameters) { + connectionService.getConnectionParameters(dataSource, cloneSourceIdentifier) + .success(function parametersReceived(parameters) { $scope.parameters = parameters; }); } @@ -332,7 +350,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i * Cancels all pending edits, returning to the management page. */ $scope.cancel = function cancel() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }; /** @@ -340,7 +358,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i * which is prepopulated with the data from the connection currently being edited. */ $scope.cloneConnection = function cloneConnection() { - $location.path('/manage/connections').search('clone', identifier); + $location.path('/manage/' + encodeURIComponent(dataSource) + '/connections').search('clone', identifier); }; /** @@ -352,9 +370,9 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i $scope.connection.parameters = $scope.parameters; // Save the connection - connectionService.saveConnection($scope.connection) + connectionService.saveConnection(dataSource, $scope.connection) .success(function savedConnection() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }) // Notify of any errors @@ -402,9 +420,9 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i var deleteConnectionImmediately = function deleteConnectionImmediately() { // Delete the connection - connectionService.deleteConnection($scope.connection) + connectionService.deleteConnection(dataSource, $scope.connection) .success(function deletedConnection() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }) // Notify of any errors diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js index 64fb03b08..1de6c7127 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js @@ -51,6 +51,14 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' } }; + /** + * The unique identifier of the data source containing the connection group + * being edited. + * + * @type String + */ + var dataSource = $routeParams.dataSource; + /** * The identifier of the connection group being edited. If a new connection * group is being created, this will not be defined. @@ -123,13 +131,14 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' }; // Pull connection group attribute schema - schemaService.getConnectionGroupAttributes().success(function attributesReceived(attributes) { + schemaService.getConnectionGroupAttributes(dataSource) + .success(function attributesReceived(attributes) { $scope.attributes = attributes; }); // Query the user's permissions for the current connection group - permissionService.getPermissions(authenticationService.getCurrentUsername()) - .success(function permissionsReceived(permissions) { + permissionService.getPermissions(dataSource, authenticationService.getCurrentUsername()) + .success(function permissionsReceived(permissions) { $scope.permissions = permissions; @@ -150,14 +159,19 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' // Pull connection group hierarchy - connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER]) + connectionGroupService.getConnectionGroupTree( + dataSource, + ConnectionGroup.ROOT_IDENTIFIER, + [PermissionSet.ObjectPermissionType.ADMINISTER] + ) .success(function connectionGroupReceived(rootGroup) { $scope.rootGroup = rootGroup; }); // If we are editing an existing connection group, pull its data if (identifier) { - connectionGroupService.getConnectionGroup(identifier).success(function connectionGroupReceived(connectionGroup) { + connectionGroupService.getConnectionGroup(dataSource, identifier) + .success(function connectionGroupReceived(connectionGroup) { $scope.connectionGroup = connectionGroup; }); } @@ -187,7 +201,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' * Cancels all pending edits, returning to the management page. */ $scope.cancel = function cancel() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }; /** @@ -197,9 +211,9 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' $scope.saveConnectionGroup = function saveConnectionGroup() { // Save the connection - connectionGroupService.saveConnectionGroup($scope.connectionGroup) + connectionGroupService.saveConnectionGroup(dataSource, $scope.connectionGroup) .success(function savedConnectionGroup() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }) // Notify of any errors @@ -247,9 +261,9 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope' var deleteConnectionGroupImmediately = function deleteConnectionGroupImmediately() { // Delete the connection group - connectionGroupService.deleteConnectionGroup($scope.connectionGroup) + connectionGroupService.deleteConnectionGroup(dataSource, $scope.connectionGroup) .success(function deletedConnectionGroup() { - $location.path('/settings/connections'); + $location.path('/settings/' + encodeURIComponent(dataSource) + '/connections'); }) // Notify of any errors diff --git a/guacamole/src/main/webapp/app/navigation/services/userPageService.js b/guacamole/src/main/webapp/app/navigation/services/userPageService.js index ef2280d37..27878ceb8 100644 --- a/guacamole/src/main/webapp/app/navigation/services/userPageService.js +++ b/guacamole/src/main/webapp/app/navigation/services/userPageService.js @@ -33,11 +33,12 @@ angular.module('navigation').factory('userPageService', ['$injector', var PermissionSet = $injector.get('PermissionSet'); // Get required services - var $q = $injector.get('$q'); - var authenticationService = $injector.get('authenticationService'); - var connectionGroupService = $injector.get('connectionGroupService'); - var dataSourceService = $injector.get('dataSourceService'); - var permissionService = $injector.get('permissionService'); + var $q = $injector.get('$q'); + var authenticationService = $injector.get('authenticationService'); + var connectionGroupService = $injector.get('connectionGroupService'); + var dataSourceService = $injector.get('dataSourceService'); + var permissionService = $injector.get('permissionService'); + var translationStringService = $injector.get('translationStringService'); var service = {}; @@ -167,12 +168,12 @@ angular.module('navigation').factory('userPageService', ['$injector', var pages = []; - var canManageUsers = false; - var canManageConnections = false; - var canManageSessions = false; + var canManageUsers = []; + var canManageConnections = []; + var canManageSessions = []; // Inspect the contents of each provided permission set - angular.forEach(permissionSets, function inspectPermissions(permissions) { + angular.forEach(permissionSets, function inspectPermissions(permissions, dataSource) { permissions = angular.copy(permissions); @@ -187,8 +188,7 @@ angular.module('navigation').factory('userPageService', ['$injector', authenticationService.getCurrentUsername()); // Determine whether the current user needs access to the user management UI - canManageUsers = canManageUsers || - + if ( // System permissions PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_USER) @@ -200,11 +200,12 @@ angular.module('navigation').factory('userPageService', ['$injector', || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.DELETE) // Permission to administer users - || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER); + || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER) + ) + canManageUsers.push(dataSource); // Determine whether the current user needs access to the connection management UI - canManageConnections = canManageConnections || - + if ( // System permissions PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION) @@ -220,18 +221,21 @@ angular.module('navigation').factory('userPageService', ['$injector', // Permission to administer connections or connection groups || PermissionSet.hasConnectionPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER) - || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER); + || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER) + ) + canManageConnections.push(dataSource); // Determine whether the current user needs access to the session management UI - canManageSessions = canManageSessions || - + if ( // A user must be a system administrator to manage sessions - PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER); + PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) + ) + canManageSessions.push(dataSource); }); // If user can manage sessions, add link to sessions management page - if (canManageSessions) { + if (canManageSessions.length) { pages.push(new PageDefinition({ name : 'USER_MENU.ACTION_MANAGE_SESSIONS', url : '/settings/sessions' @@ -239,20 +243,23 @@ angular.module('navigation').factory('userPageService', ['$injector', } // If user can manage users, add link to user management page - if (canManageUsers) { + if (canManageUsers.length) { pages.push(new PageDefinition({ name : 'USER_MENU.ACTION_MANAGE_USERS', url : '/settings/users' })); } - // If user can manage connections, add link to connections management page - if (canManageConnections) { + // If user can manage connections, add links for connection management pages + angular.forEach(canManageConnections, function addConnectionManagementLink(dataSource) { pages.push(new PageDefinition({ - name : 'USER_MENU.ACTION_MANAGE_CONNECTIONS', - url : '/settings/connections' + name : [ + 'USER_MENU.ACTION_MANAGE_CONNECTIONS', + translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME' + ], + url : '/settings/' + encodeURIComponent(dataSource) + '/connections' })); - } + }); // Add link to user preferences (always accessible) pages.push(new PageDefinition({ diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js index e1b77893f..640cb69a9 100644 --- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js +++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js @@ -41,13 +41,18 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe var PermissionSet = $injector.get('PermissionSet'); // Required services - var $location = $injector.get('$location'); + var $routeParams = $injector.get('$routeParams'); var authenticationService = $injector.get('authenticationService'); var connectionGroupService = $injector.get('connectionGroupService'); + var dataSourceService = $injector.get('dataSourceService'); var guacNotification = $injector.get('guacNotification'); var permissionService = $injector.get('permissionService'); - // Identifier of the current user + /** + * The identifier of the current user. + * + * @type String + */ var currentUsername = authenticationService.getCurrentUsername(); /** @@ -62,12 +67,19 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe } }; + /** + * The identifier of the currently-selected data source. + * + * @type String + */ + $scope.dataSource = $routeParams.dataSource; + /** * The root connection group of the connection group hierarchy. * - * @type ConnectionGroup + * @type Object. */ - $scope.rootGroup = null; + $scope.rootGroups = null; /** * Whether the current user can manage connections. If the current @@ -98,7 +110,7 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe * All permissions associated with the current user, or null if the * user's permissions have not yet been loaded. * - * @type PermissionSet + * @type Object. */ $scope.permissions = null; @@ -111,20 +123,25 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe */ $scope.isLoaded = function isLoaded() { - return $scope.rootGroup !== null - && $scope.permissions !== null - && $scope.canManageConnections !== null - && $scope.canCreateConnections !== null - && $scope.canCreateConnectionGroups !== null; + return $scope.rootGroup !== null + && $scope.permissions !== null; }; + $scope.canManageConnections = true; + $scope.canCreateConnections = true; + $scope.canCreateConnectionGroups = true; + // Retrieve current permissions - permissionService.getPermissions(currentUsername) - .success(function permissionsRetrieved(permissions) { + dataSourceService.apply( + permissionService.getPermissions, + [$scope.dataSource], + currentUsername + ) + .then(function permissionsRetrieved(permissions) { $scope.permissions = permissions; - +/* // Ignore permission to update root group PermissionSet.removeConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, ConnectionGroup.ROOT_IDENTIFIER); @@ -154,14 +171,18 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe // Return to home if there's nothing to do here if (!$scope.canManageConnections) $location.path('/'); - +*/ }); // Retrieve all connections for which we have UPDATE or DELETE permission - connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, - [PermissionSet.ObjectPermissionType.UPDATE, PermissionSet.ObjectPermissionType.DELETE]) - .success(function connectionGroupReceived(rootGroup) { - $scope.rootGroup = rootGroup; + dataSourceService.apply( + connectionGroupService.getConnectionGroupTree, + [$scope.dataSource], + ConnectionGroup.ROOT_IDENTIFIER, + [PermissionSet.ObjectPermissionType.UPDATE, PermissionSet.ObjectPermissionType.DELETE] + ) + .then(function connectionGroupsReceived(rootGroups) { + $scope.rootGroups = rootGroups; }); }] diff --git a/guacamole/src/main/webapp/app/settings/templates/connection.html b/guacamole/src/main/webapp/app/settings/templates/connection.html index f2d1a5550..7514ade8e 100644 --- a/guacamole/src/main/webapp/app/settings/templates/connection.html +++ b/guacamole/src/main/webapp/app/settings/templates/connection.html @@ -1,4 +1,4 @@ - +