mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUAC-1133 Split out session, user, and connection manage pages, rudimentary session management interface.
This commit is contained in:
		| @@ -74,12 +74,30 @@ angular.module('index').config(['$routeProvider', '$locationProvider', | |||||||
|             resolve       : { updateCurrentToken: updateCurrentToken } |             resolve       : { updateCurrentToken: updateCurrentToken } | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|         // Management screen |         // Connection management screen | ||||||
|         .when('/manage/', { |         .when('/manage/modules/connections/', { | ||||||
|             title         : 'APP.NAME', |             title         : 'APP.NAME', | ||||||
|             bodyClassName : 'manage', |             bodyClassName : 'manage', | ||||||
|             templateUrl   : 'app/manage/templates/manage.html', |             templateUrl   : 'app/manage/templates/manageConnections.html', | ||||||
|             controller    : 'manageController', |             controller    : 'manageConnectionsController', | ||||||
|  |             resolve       : { updateCurrentToken: updateCurrentToken } | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // User management screen | ||||||
|  |         .when('/manage/modules/users/', { | ||||||
|  |             title         : 'APP.NAME', | ||||||
|  |             bodyClassName : 'manage', | ||||||
|  |             templateUrl   : 'app/manage/templates/manageUsers.html', | ||||||
|  |             controller    : 'manageUsersController', | ||||||
|  |             resolve       : { updateCurrentToken: updateCurrentToken } | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Session management screen | ||||||
|  |         .when('/manage/modules/sessions/', { | ||||||
|  |             title         : 'APP.NAME', | ||||||
|  |             bodyClassName : 'manage', | ||||||
|  |             templateUrl   : 'app/manage/templates/manageSessions.html', | ||||||
|  |             controller    : 'manageSessionsController', | ||||||
|             resolve       : { updateCurrentToken: updateCurrentToken } |             resolve       : { updateCurrentToken: updateCurrentToken } | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,15 +21,14 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * The controller for the administration page. |  * The controller for the connection and connection group administration page. | ||||||
|  */ |  */ | ||||||
| angular.module('manage').controller('manageController', ['$scope', '$injector',  | angular.module('manage').controller('manageConnectionsController', ['$scope', '$injector',  | ||||||
|         function manageController($scope, $injector) { |         function manageConnectionsController($scope, $injector) { | ||||||
| 
 | 
 | ||||||
|     // Required types
 |     // Required types
 | ||||||
|     var ConnectionGroup = $injector.get('ConnectionGroup'); |     var ConnectionGroup = $injector.get('ConnectionGroup'); | ||||||
|     var PermissionSet   = $injector.get('PermissionSet'); |     var PermissionSet   = $injector.get('PermissionSet'); | ||||||
|     var User            = $injector.get('User'); |  | ||||||
| 
 | 
 | ||||||
|     // Required services
 |     // Required services
 | ||||||
|     var $location              = $injector.get('$location'); |     var $location              = $injector.get('$location'); | ||||||
| @@ -37,7 +36,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|     var connectionGroupService = $injector.get('connectionGroupService'); |     var connectionGroupService = $injector.get('connectionGroupService'); | ||||||
|     var guacNotification       = $injector.get('guacNotification'); |     var guacNotification       = $injector.get('guacNotification'); | ||||||
|     var permissionService      = $injector.get('permissionService'); |     var permissionService      = $injector.get('permissionService'); | ||||||
|     var userService            = $injector.get('userService'); |  | ||||||
| 
 | 
 | ||||||
|     // Identifier of the current user
 |     // Identifier of the current user
 | ||||||
|     var currentUserID = authenticationService.getCurrentUserID(); |     var currentUserID = authenticationService.getCurrentUserID(); | ||||||
| @@ -47,20 +45,13 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|      * closes the currently-shown status dialog. |      * closes the currently-shown status dialog. | ||||||
|      */ |      */ | ||||||
|     var ACKNOWLEDGE_ACTION = { |     var ACKNOWLEDGE_ACTION = { | ||||||
|         name        : "MANAGE.ACTION_ACKNOWLEDGE", |         name        : "MANAGE_CONNECTION.ACTION_ACKNOWLEDGE", | ||||||
|         // Handle action
 |         // Handle action
 | ||||||
|         callback    : function acknowledgeCallback() { |         callback    : function acknowledgeCallback() { | ||||||
|             guacNotification.showStatus(false); |             guacNotification.showStatus(false); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * All visible users. |  | ||||||
|      * |  | ||||||
|      * @type User[] |  | ||||||
|      */ |  | ||||||
|     $scope.users = null; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * The root connection group of the connection group hierarchy. |      * The root connection group of the connection group hierarchy. | ||||||
|      * |      * | ||||||
| @@ -68,14 +59,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|      */ |      */ | ||||||
|     $scope.rootGroup = null; |     $scope.rootGroup = null; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Whether the current user can manage users. If the current permissions |  | ||||||
|      * have not yet been loaded, this will be null. |  | ||||||
|      * |  | ||||||
|      * @type Boolean |  | ||||||
|      */ |  | ||||||
|     $scope.canManageUsers = null; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Whether the current user can manage connections. If the current |      * Whether the current user can manage connections. If the current | ||||||
|      * permissions have not yet been loaded, this will be null. |      * permissions have not yet been loaded, this will be null. | ||||||
| @@ -84,14 +67,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|      */ |      */ | ||||||
|     $scope.canManageConnections = null; |     $scope.canManageConnections = null; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Whether the current user can create new users. If the current |  | ||||||
|      * permissions have not yet been loaded, this will be null. |  | ||||||
|      * |  | ||||||
|      * @type Boolean |  | ||||||
|      */ |  | ||||||
|     $scope.canCreateUsers = null; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Whether the current user can create new connections. If the current |      * Whether the current user can create new connections. If the current | ||||||
|      * permissions have not yet been loaded, this will be null. |      * permissions have not yet been loaded, this will be null. | ||||||
| @@ -108,14 +83,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|      */ |      */ | ||||||
|     $scope.canCreateConnectionGroups = null; |     $scope.canCreateConnectionGroups = null; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * The name of the new user to create, if any, when user creation is |  | ||||||
|      * requested via newUser(). |  | ||||||
|      * |  | ||||||
|      * @type String |  | ||||||
|      */ |  | ||||||
|     $scope.newUsername = ""; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * All permissions associated with the current user, or null if the user's |      * All permissions associated with the current user, or null if the user's | ||||||
|      * permissions have not yet been loaded. |      * permissions have not yet been loaded. | ||||||
| @@ -133,12 +100,9 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|      */ |      */ | ||||||
|     $scope.isLoaded = function isLoaded() { |     $scope.isLoaded = function isLoaded() { | ||||||
| 
 | 
 | ||||||
|         return $scope.users                     !== null |         return $scope.rootGroup                 !== null | ||||||
|             && $scope.rootGroup                 !== null |  | ||||||
|             && $scope.permissions               !== null |             && $scope.permissions               !== null | ||||||
|             && $scope.canManageUsers            !== null |  | ||||||
|             && $scope.canManageConnections      !== null |             && $scope.canManageConnections      !== null | ||||||
|             && $scope.canCreateUsers            !== null |  | ||||||
|             && $scope.canCreateConnections      !== null |             && $scope.canCreateConnections      !== null | ||||||
|             && $scope.canCreateConnectionGroups !== null; |             && $scope.canCreateConnectionGroups !== null; | ||||||
| 
 | 
 | ||||||
| @@ -153,11 +117,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|         // Ignore permission to update root group
 |         // Ignore permission to update root group
 | ||||||
|         PermissionSet.removeConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, ConnectionGroup.ROOT_IDENTIFIER); |         PermissionSet.removeConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, ConnectionGroup.ROOT_IDENTIFIER); | ||||||
| 
 | 
 | ||||||
|         // Determine whether the current user can create new users
 |  | ||||||
|         $scope.canCreateUsers = |  | ||||||
|                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) |  | ||||||
|             || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_USER); |  | ||||||
| 
 |  | ||||||
|         // Determine whether the current user can create new users
 |         // Determine whether the current user can create new users
 | ||||||
|         $scope.canCreateConnections = |         $scope.canCreateConnections = | ||||||
|                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) |                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||||
| @@ -168,12 +127,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) |                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||||
|             || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP); |             || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP); | ||||||
| 
 | 
 | ||||||
|         // Determine whether the current user can manage other users
 |  | ||||||
|         $scope.canManageUsers = |  | ||||||
|                $scope.canCreateUsers |  | ||||||
|             || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE) |  | ||||||
|             || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.DELETE); |  | ||||||
| 
 |  | ||||||
|         // Determine whether the current user can manage other connections or groups
 |         // Determine whether the current user can manage other connections or groups
 | ||||||
|         $scope.canManageConnections = |         $scope.canManageConnections = | ||||||
| 
 | 
 | ||||||
| @@ -188,7 +141,7 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|             || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE); |             || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE); | ||||||
| 
 | 
 | ||||||
|         // Return to home if there's nothing to do here
 |         // Return to home if there's nothing to do here
 | ||||||
|         if (!$scope.canManageUsers && !$scope.canManageConnections) |         if (!$scope.canManageConnections) | ||||||
|             $location.path('/'); |             $location.path('/'); | ||||||
|          |          | ||||||
|     }); |     }); | ||||||
| @@ -200,50 +153,4 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|         $scope.rootGroup = rootGroup; |         $scope.rootGroup = rootGroup; | ||||||
|     }); |     }); | ||||||
|      |      | ||||||
|     // Retrieve all users for whom we have UPDATE or DELETE permission
 |  | ||||||
|     userService.getUsers([PermissionSet.ObjectPermissionType.UPDATE,  |  | ||||||
|         PermissionSet.ObjectPermissionType.DELETE]) |  | ||||||
|     .success(function usersReceived(users) { |  | ||||||
| 
 |  | ||||||
|         // Display only other users, not self
 |  | ||||||
|         $scope.users = users.filter(function isNotSelf(user) { |  | ||||||
|             return user.username !== currentUserID; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Creates a new user having the username specified in the user creation |  | ||||||
|      * interface. |  | ||||||
|      */ |  | ||||||
|     $scope.newUser = function newUser() { |  | ||||||
| 
 |  | ||||||
|         // Create user skeleton
 |  | ||||||
|         var user = new User({ |  | ||||||
|             username: $scope.newUsername || '' |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         // Create specified user
 |  | ||||||
|         userService.createUser(user) |  | ||||||
| 
 |  | ||||||
|         // Add user to visible list upon success
 |  | ||||||
|         .success(function userCreated() { |  | ||||||
|             $scope.users.push(user); |  | ||||||
|         }) |  | ||||||
| 
 |  | ||||||
|         // Notify of any errors
 |  | ||||||
|         .error(function userCreationFailed(error) { |  | ||||||
|             guacNotification.showStatus({ |  | ||||||
|                 'className'  : 'error', |  | ||||||
|                 'title'      : 'MANAGE.DIALOG_HEADER_ERROR', |  | ||||||
|                 'text'       : error.message, |  | ||||||
|                 'actions'    : [ ACKNOWLEDGE_ACTION ] |  | ||||||
|             }); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         // Reset username
 |  | ||||||
|         $scope.newUsername = ""; |  | ||||||
| 
 |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
| }]); | }]); | ||||||
| @@ -0,0 +1,220 @@ | |||||||
|  | /* | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The controller for the user session administration page. | ||||||
|  |  */ | ||||||
|  | angular.module('manage').controller('manageSessionsController', ['$scope', '$injector',  | ||||||
|  |         function manageSessionsController($scope, $injector) { | ||||||
|  |  | ||||||
|  |     // Required types | ||||||
|  |     var ActiveTunnelWrapper = $injector.get('ActiveTunnelWrapper'); | ||||||
|  |     var ConnectionGroup     = $injector.get('ConnectionGroup'); | ||||||
|  |  | ||||||
|  |     // Required services | ||||||
|  |     var authenticationService  = $injector.get('authenticationService'); | ||||||
|  |     var connectionGroupService = $injector.get('connectionGroupService'); | ||||||
|  |     var guacNotification       = $injector.get('guacNotification'); | ||||||
|  |     var permissionService      = $injector.get('permissionService'); | ||||||
|  |     var tunnelService          = $injector.get('tunnelService'); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The root connection group of the connection group hierarchy. | ||||||
|  |      * | ||||||
|  |      * @type ConnectionGroup | ||||||
|  |      */ | ||||||
|  |     $scope.rootGroup = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * All permissions associated with the current user, or null if the user's | ||||||
|  |      * permissions have not yet been loaded. | ||||||
|  |      * | ||||||
|  |      * @type PermissionSet | ||||||
|  |      */ | ||||||
|  |     $scope.permissions = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The ActiveTunnelWrappers of all active sessions accessible by the current  | ||||||
|  |      * user, or null if the tunnels have not yet been loaded. | ||||||
|  |      * | ||||||
|  |      * @type ActiveTunnelWrapper[] | ||||||
|  |      */ | ||||||
|  |     $scope.wrappers = null; | ||||||
|  |  | ||||||
|  |     // Query the user's permissions | ||||||
|  |     permissionService.getPermissions(authenticationService.getCurrentUserID()) | ||||||
|  |             .success(function permissionsReceived(permissions) { | ||||||
|  |         $scope.permissions = permissions; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Map of all visible connections by object identifier. | ||||||
|  |      * | ||||||
|  |      * @type Object.<String, Connection> | ||||||
|  |      */ | ||||||
|  |     $scope.connections = {}; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * The count of currently selected tunnel wrappers. | ||||||
|  |      *  | ||||||
|  |      * @type Number | ||||||
|  |      */ | ||||||
|  |     var selectedWrapperCount = 0; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds the given connection to the internal set of visible | ||||||
|  |      * connections. | ||||||
|  |      *  | ||||||
|  |      * @param {Connection} connection | ||||||
|  |      *     The connection to add to the internal set of visible connections. | ||||||
|  |      */ | ||||||
|  |     var addConnection = function addConnection(connection) { | ||||||
|  |  | ||||||
|  |         // Add given connection to set of visible connections | ||||||
|  |         $scope.connections[connection.identifier] = connection; | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds all descendant connections of the given connection group to the | ||||||
|  |      * internal set of connections. | ||||||
|  |      *  | ||||||
|  |      * @param {ConnectionGroup} connectionGroup | ||||||
|  |      *     The connection group whose descendant connections should be added to | ||||||
|  |      *     the internal set of connections. | ||||||
|  |      */ | ||||||
|  |     var addDescendantConnections  = function addDescendantConnections(connectionGroup) { | ||||||
|  |  | ||||||
|  |         // Add all child connections | ||||||
|  |         if (connectionGroup.childConnections) | ||||||
|  |             connectionGroup.childConnections.forEach(addConnection); | ||||||
|  |  | ||||||
|  |         // Add all child connection groups | ||||||
|  |         if (connectionGroup.childConnectionGroups) | ||||||
|  |             connectionGroup.childConnectionGroups.forEach(addDescendantConnections); | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     // Retrieve all connections  | ||||||
|  |     connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER) | ||||||
|  |     .success(function connectionGroupReceived(rootGroup) { | ||||||
|  |         $scope.rootGroup = rootGroup; | ||||||
|  |         addDescendantConnections($scope.rootGroup); | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     // Query active sessions | ||||||
|  |     tunnelService.getActiveTunnels().success(function sessionsRetrieved(tunnels) { | ||||||
|  |          | ||||||
|  |         // Wrap all active tunnels for sake of display | ||||||
|  |         $scope.wrappers = []; | ||||||
|  |         tunnels.forEach(function wrapActiveTunnel(tunnel) { | ||||||
|  |            $scope.wrappers.push(new ActiveTunnelWrapper(tunnel));  | ||||||
|  |         }); | ||||||
|  |          | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns whether critical data has completed being loaded. | ||||||
|  |      * | ||||||
|  |      * @returns {Boolean} | ||||||
|  |      *     true if enough data has been loaded for the user interface to be | ||||||
|  |      *     useful, false otherwise. | ||||||
|  |      */ | ||||||
|  |     $scope.isLoaded = function isLoaded() { | ||||||
|  |  | ||||||
|  |         return $scope.wrappers             !== null | ||||||
|  |             && $scope.permissions          !== null | ||||||
|  |             && $scope.rootGroup            !== null; | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * An action to be provided along with the object sent to showStatus which | ||||||
|  |      * closes the currently-shown status dialog. | ||||||
|  |      */ | ||||||
|  |     var CANCEL_ACTION = { | ||||||
|  |         name        : "MANAGE_USER.ACTION_CANCEL", | ||||||
|  |         // Handle action | ||||||
|  |         callback    : function cancelCallback() { | ||||||
|  |             guacNotification.showStatus(false); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * An action to be provided along with the object sent to showStatus which | ||||||
|  |      * immediately deletes the currently selected sessions. | ||||||
|  |      */ | ||||||
|  |     var DELETE_ACTION = { | ||||||
|  |         name        : "MANAGE_SESSION.ACTION_DELETE", | ||||||
|  |         className   : "danger", | ||||||
|  |         // Handle action | ||||||
|  |         callback    : function deleteCallback() { | ||||||
|  |             deleteSessionsImmediately(); | ||||||
|  |             guacNotification.showStatus(false); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * Immediately deletes the selected sessions, without prompting the user for | ||||||
|  |      * confirmation. | ||||||
|  |      */ | ||||||
|  |     var deleteSessionsImmediately = function deleteSessionsImmediately() { | ||||||
|  |         // TODO: Use a batch delete function to delete the sessions. | ||||||
|  |     };  | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * Delete all selected sessions, prompting the user first to confirm that  | ||||||
|  |      * deletion is desired. | ||||||
|  |      */ | ||||||
|  |     $scope.deleteSessions = function deleteSessions() { | ||||||
|  |         // Confirm deletion request | ||||||
|  |         guacNotification.showStatus({ | ||||||
|  |             'title'      : 'MANAGE_SESSION.DIALOG_HEADER_CONFIRM_DELETE', | ||||||
|  |             'text'       : 'MANAGE_SESSION.TEXT_CONFIRM_DELETE', | ||||||
|  |             'actions'    : [ DELETE_ACTION, CANCEL_ACTION] | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * Returns whether the selected sessions can be deleted. | ||||||
|  |      *  | ||||||
|  |      * @returns {Boolean} | ||||||
|  |      *     true if selected sessions can be deleted, false otherwise. | ||||||
|  |      */ | ||||||
|  |     $scope.canDeleteSessions = function canDeleteSessions() { | ||||||
|  |         return selectedWrapperCount > 0; | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * Called whenever a tunnel wrapper changes selected status. | ||||||
|  |      *  | ||||||
|  |      * @param {Boolean} selected | ||||||
|  |      *     Whether the wrapper is now selected. | ||||||
|  |      */ | ||||||
|  |     $scope.wrapperSelectionChange = function wrapperSelectionChange(selected) { | ||||||
|  |         if (selected) | ||||||
|  |             selectedWrapperCount++; | ||||||
|  |         else | ||||||
|  |             selectedWrapperCount--; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  | }]); | ||||||
| @@ -0,0 +1,179 @@ | |||||||
|  | /* | ||||||
|  |  * 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. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The controller for the user administration page. | ||||||
|  |  */ | ||||||
|  | angular.module('manage').controller('manageUsersController', ['$scope', '$injector',  | ||||||
|  |         function manageUsersController($scope, $injector) { | ||||||
|  |  | ||||||
|  |     // Required types | ||||||
|  |     var PermissionSet   = $injector.get('PermissionSet'); | ||||||
|  |     var User            = $injector.get('User'); | ||||||
|  |  | ||||||
|  |     // Required services | ||||||
|  |     var $location              = $injector.get('$location'); | ||||||
|  |     var authenticationService  = $injector.get('authenticationService'); | ||||||
|  |     var guacNotification       = $injector.get('guacNotification'); | ||||||
|  |     var permissionService      = $injector.get('permissionService'); | ||||||
|  |     var userService            = $injector.get('userService'); | ||||||
|  |  | ||||||
|  |     // Identifier of the current user | ||||||
|  |     var currentUserID = authenticationService.getCurrentUserID(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * An action to be provided along with the object sent to showStatus which | ||||||
|  |      * closes the currently-shown status dialog. | ||||||
|  |      */ | ||||||
|  |     var ACKNOWLEDGE_ACTION = { | ||||||
|  |         name        : "MANAGE_USER.ACTION_ACKNOWLEDGE", | ||||||
|  |         // Handle action | ||||||
|  |         callback    : function acknowledgeCallback() { | ||||||
|  |             guacNotification.showStatus(false); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * All visible users. | ||||||
|  |      * | ||||||
|  |      * @type User[] | ||||||
|  |      */ | ||||||
|  |     $scope.users = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Whether the current user can manage users. If the current permissions | ||||||
|  |      * have not yet been loaded, this will be null. | ||||||
|  |      * | ||||||
|  |      * @type Boolean | ||||||
|  |      */ | ||||||
|  |     $scope.canManageUsers = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Whether the current user can create new users. If the current | ||||||
|  |      * permissions have not yet been loaded, this will be null. | ||||||
|  |      * | ||||||
|  |      * @type Boolean | ||||||
|  |      */ | ||||||
|  |     $scope.canCreateUsers = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The name of the new user to create, if any, when user creation is | ||||||
|  |      * requested via newUser(). | ||||||
|  |      * | ||||||
|  |      * @type String | ||||||
|  |      */ | ||||||
|  |     $scope.newUsername = ""; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * All permissions associated with the current user, or null if the user's | ||||||
|  |      * permissions have not yet been loaded. | ||||||
|  |      * | ||||||
|  |      * @type PermissionSet | ||||||
|  |      */ | ||||||
|  |     $scope.permissions = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns whether critical data has completed being loaded. | ||||||
|  |      * | ||||||
|  |      * @returns {Boolean} | ||||||
|  |      *     true if enough data has been loaded for the user interface to be | ||||||
|  |      *     useful, false otherwise. | ||||||
|  |      */ | ||||||
|  |     $scope.isLoaded = function isLoaded() { | ||||||
|  |  | ||||||
|  |         return $scope.users                     !== null | ||||||
|  |             && $scope.permissions               !== null | ||||||
|  |             && $scope.canManageUsers            !== null | ||||||
|  |             && $scope.canCreateUsers            !== null; | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     // Retrieve current permissions | ||||||
|  |     permissionService.getPermissions(currentUserID) | ||||||
|  |     .success(function permissionsRetrieved(permissions) { | ||||||
|  |  | ||||||
|  |         $scope.permissions = permissions; | ||||||
|  |  | ||||||
|  |         // Determine whether the current user can create new users | ||||||
|  |         $scope.canCreateUsers = | ||||||
|  |                PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||||
|  |             || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_USER); | ||||||
|  |  | ||||||
|  |         // Determine whether the current user can manage other users | ||||||
|  |         $scope.canManageUsers = | ||||||
|  |                $scope.canCreateUsers | ||||||
|  |             || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE) | ||||||
|  |             || PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.DELETE); | ||||||
|  |  | ||||||
|  |         // Return to home if there's nothing to do here | ||||||
|  |         if (!$scope.canManageUsers) | ||||||
|  |             $location.path('/'); | ||||||
|  |          | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     // Retrieve all users for whom we have UPDATE or DELETE permission | ||||||
|  |     userService.getUsers([PermissionSet.ObjectPermissionType.UPDATE,  | ||||||
|  |         PermissionSet.ObjectPermissionType.DELETE]) | ||||||
|  |     .success(function usersReceived(users) { | ||||||
|  |  | ||||||
|  |         // Display only other users, not self | ||||||
|  |         $scope.users = users.filter(function isNotSelf(user) { | ||||||
|  |             return user.username !== currentUserID; | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Creates a new user having the username specified in the user creation | ||||||
|  |      * interface. | ||||||
|  |      */ | ||||||
|  |     $scope.newUser = function newUser() { | ||||||
|  |  | ||||||
|  |         // Create user skeleton | ||||||
|  |         var user = new User({ | ||||||
|  |             username: $scope.newUsername || '' | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         // Create specified user | ||||||
|  |         userService.createUser(user) | ||||||
|  |  | ||||||
|  |         // Add user to visible list upon success | ||||||
|  |         .success(function userCreated() { | ||||||
|  |             $scope.users.push(user); | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Notify of any errors | ||||||
|  |         .error(function userCreationFailed(error) { | ||||||
|  |             guacNotification.showStatus({ | ||||||
|  |                 'className'  : 'error', | ||||||
|  |                 'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR', | ||||||
|  |                 'text'       : error.message, | ||||||
|  |                 'actions'    : [ ACKNOWLEDGE_ACTION ] | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         // Reset username | ||||||
|  |         $scope.newUsername = ""; | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  | }]); | ||||||
| @@ -0,0 +1,60 @@ | |||||||
|  | <!-- | ||||||
|  | Copyright 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. | ||||||
|  | --> | ||||||
|  |  | ||||||
|  | <div class="view" ng-class="{loading: !isLoaded()}"> | ||||||
|  |  | ||||||
|  |     <div class="header"> | ||||||
|  |         <h2>{{'MANAGE_CONNECTION.SECTION_HEADER_CONNECTIONS' | translate}}</h2> | ||||||
|  |         <guac-user-menu permissions="permissions"></guac-user-menu> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <!-- Connection management --> | ||||||
|  |     <div class="settings section" ng-show="canManageConnections"> | ||||||
|  |         <div class="connections"> | ||||||
|  |  | ||||||
|  |             <p>{{'MANAGE_CONNECTION.HELP_CONNECTIONS' | translate}}</p> | ||||||
|  |  | ||||||
|  |             <!-- Connection/group creation buttons --> | ||||||
|  |             <div class="connection-add-form"> | ||||||
|  |  | ||||||
|  |                 <a class="add-connection button" | ||||||
|  |                    ng-show="canCreateConnections" | ||||||
|  |                    href="#/manage/connections/">{{'MANAGE_CONNECTION.ACTION_NEW_CONNECTION' | translate}}</a> | ||||||
|  |  | ||||||
|  |                 <a class="add-connection-group button" | ||||||
|  |                    ng-show="canCreateConnectionGroups" | ||||||
|  |                    href="#/manage/connectionGroups/">{{'MANAGE_CONNECTION.ACTION_NEW_CONNECTION_GROUP' | translate}}</a> | ||||||
|  |  | ||||||
|  |             </div> | ||||||
|  |  | ||||||
|  |             <!-- List of accessible connections and groups --> | ||||||
|  |             <div class="connection-list"> | ||||||
|  |                 <guac-group-list | ||||||
|  |                     page-size="25" | ||||||
|  |                     connection-group="rootGroup" | ||||||
|  |                     connection-template="'app/manage/templates/connection.html'" | ||||||
|  |                     connection-group-template="'app/manage/templates/connectionGroup.html'"/> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  | </div> | ||||||
| @@ -0,0 +1,80 @@ | |||||||
|  | <!-- | ||||||
|  | Copyright 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. | ||||||
|  | --> | ||||||
|  |  | ||||||
|  | <div class="view" ng-class="{loading: !isLoaded()}"> | ||||||
|  |  | ||||||
|  |     <div class="header"> | ||||||
|  |         <h2>{{'MANAGE_SESSION.SECTION_HEADER_SESSIONS' | translate}}</h2> | ||||||
|  |         <guac-user-menu permissions="permissions"></guac-user-menu> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <!-- User Session management --> | ||||||
|  |     <div class="settings section"> | ||||||
|  |         <div class="sessions"> | ||||||
|  |  | ||||||
|  |             <p>{{'MANAGE_SESSION.HELP_SESSIONS' | translate}}</p> | ||||||
|  |             <button class="delete-sessions" ng-disabled="!canDeleteSessions()" ng-click="deleteSessions()">{{'MANAGE_SESSION.ACTION_DELETE' | translate}}</button> | ||||||
|  |  | ||||||
|  |             <!-- List of current user sessions --> | ||||||
|  |             <table class="session-list"> | ||||||
|  |                 <thead> | ||||||
|  |                     <tr> | ||||||
|  |                         <th></th> | ||||||
|  |                         <th> | ||||||
|  |                             {{'MANAGE_SESSION.TABLE_HEADER_SESSION_USERNAME' | translate}} | ||||||
|  |                         </th> | ||||||
|  |                         <th> | ||||||
|  |                             {{'MANAGE_SESSION.TABLE_HEADER_SESSION_STARTDATE' | translate}} | ||||||
|  |                         </th> | ||||||
|  |                         <th> | ||||||
|  |                             {{'MANAGE_SESSION.TABLE_HEADER_SESSION_REMOTEHOST' | translate}} | ||||||
|  |                         </th> | ||||||
|  |                         <th> | ||||||
|  |                             {{'MANAGE_SESSION.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}} | ||||||
|  |                         </th> | ||||||
|  |                     </tr> | ||||||
|  |                 </thead> | ||||||
|  |                 <tbody> | ||||||
|  |                     <tr ng-repeat="wrapper in wrapperPage" class="session"> | ||||||
|  |                         <td> | ||||||
|  |                             <input ng-change="wrapperSelectionChange(wrapper.checked)" type="checkbox" ng-model="wrapper.checked" /> | ||||||
|  |                         </td> | ||||||
|  |                         <td> | ||||||
|  |                             {{wrapper.tunnel.username}} | ||||||
|  |                         </td> | ||||||
|  |                         <td> | ||||||
|  |                             {{wrapper.tunnel.startDate | date:'short'}} | ||||||
|  |                         </td> | ||||||
|  |                         <td> | ||||||
|  |                             {{wrapper.tunnel.remoteHost}} | ||||||
|  |                         </td> | ||||||
|  |                         <td> | ||||||
|  |                             {{connections[wrapper.tunnel.identifier].name}} | ||||||
|  |                         </td> | ||||||
|  |                     </tr> | ||||||
|  |                 </tbody> | ||||||
|  |             </table> | ||||||
|  |             <guac-pager page="wrapperPage" page-size="25" items="wrappers | orderBy : 'username'"></guac-pager> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  | </div> | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| <!-- | <!-- | ||||||
| Copyright 2014 Glyptodon LLC. | Copyright 2015 Glyptodon LLC. | ||||||
| 
 | 
 | ||||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
| of this software and associated documentation files (the "Software"), to deal | of this software and associated documentation files (the "Software"), to deal | ||||||
| @@ -23,21 +23,20 @@ THE SOFTWARE. | |||||||
| <div class="view" ng-class="{loading: !isLoaded()}"> | <div class="view" ng-class="{loading: !isLoaded()}"> | ||||||
| 
 | 
 | ||||||
|     <div class="header"> |     <div class="header"> | ||||||
|         <h2>{{'MANAGE.SECTION_HEADER_ADMINISTRATION' | translate}}</h2> |         <h2>{{'MANAGE_USER.SECTION_HEADER_USERS' | translate}}</h2> | ||||||
|         <guac-user-menu permissions="permissions"></guac-user-menu> |         <guac-user-menu permissions="permissions"></guac-user-menu> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <!-- User management --> |     <!-- User management --> | ||||||
|     <div class="settings section" ng-show="canManageUsers"> |     <div class="settings section" ng-show="canManageUsers"> | ||||||
|         <h3>{{'MANAGE.SECTION_HEADER_USERS' | translate}}</h3> |  | ||||||
|         <div class="users"> |         <div class="users"> | ||||||
| 
 | 
 | ||||||
|             <p>{{'MANAGE.HELP_USERS' | translate}}</p> |             <p>{{'MANAGE_USER.HELP_USERS' | translate}}</p> | ||||||
| 
 | 
 | ||||||
|             <!-- User creation form --> |             <!-- User creation form --> | ||||||
|             <div class="user-add-form" ng-show="canCreateUsers"> |             <div class="user-add-form" ng-show="canCreateUsers"> | ||||||
|                 <input type="text" ng-model="newUsername" class="name username" autocorrect="off" autocapitalize="off"/> |                 <input type="text" ng-model="newUsername" class="name username" autocorrect="off" autocapitalize="off"/> | ||||||
|                 <button class="add-user" ng-click="newUser()">{{'MANAGE.ACTION_NEW_USER' | translate}}</button> |                 <button class="add-user" ng-click="newUser()">{{'MANAGE_USER.ACTION_NEW_USER' | translate}}</button> | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|             <!-- List of users this user has access to --> |             <!-- List of users this user has access to --> | ||||||
| @@ -53,39 +52,9 @@ THE SOFTWARE. | |||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|             <!-- Pager controls for user list --> |             <!-- Pager controls for user list --> | ||||||
|             <guac-pager page="userPage" items="users | orderBy : 'username'"></guac-pager> |             <guac-pager page="userPage" page-size="25" items="users | orderBy : 'username'"></guac-pager> | ||||||
| 
 | 
 | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <!-- Connection management --> |  | ||||||
|     <div class="settings section" ng-show="canManageConnections"> |  | ||||||
|         <h3>{{'MANAGE.SECTION_HEADER_CONNECTIONS' | translate}}</h3> |  | ||||||
|         <div class="connections"> |  | ||||||
| 
 |  | ||||||
|             <p>{{'MANAGE.HELP_CONNECTIONS' | translate}}</p> |  | ||||||
| 
 |  | ||||||
|             <!-- Connection/group creation buttons --> |  | ||||||
|             <div class="connection-add-form"> |  | ||||||
| 
 |  | ||||||
|                 <a class="add-connection button" |  | ||||||
|                    ng-show="canCreateConnections" |  | ||||||
|                    href="#/manage/connections/">{{'MANAGE.ACTION_NEW_CONNECTION' | translate}}</a> |  | ||||||
| 
 |  | ||||||
|                 <a class="add-connection-group button" |  | ||||||
|                    ng-show="canCreateConnectionGroups" |  | ||||||
|                    href="#/manage/connectionGroups/">{{'MANAGE.ACTION_NEW_CONNECTION_GROUP' | translate}}</a> |  | ||||||
| 
 |  | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
|             <!-- List of accessible connections and groups --> |  | ||||||
|             <div class="connection-list"> |  | ||||||
|                 <guac-group-list |  | ||||||
|                     connection-group="rootGroup" |  | ||||||
|                     connection-template="'app/manage/templates/connection.html'" |  | ||||||
|                     connection-group-template="'app/manage/templates/connectionGroup.html'"/> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| 
 |  | ||||||
| </div> | </div> | ||||||
| @@ -20,12 +20,38 @@ | |||||||
|  * THE SOFTWARE. |  * THE SOFTWARE. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| .manage .connection-list .group-list-page, | /** | ||||||
| .manage .user-list { |  * A service for defining the ActiveTunnelWrapper class. | ||||||
|     border: 1px solid rgba(0, 0, 0, 0.25); |  */ | ||||||
|     min-height: 15em; | angular.module('manage').factory('ActiveTunnelWrapper', [ | ||||||
|     -moz-border-radius: 0.2em; |     function defineActiveTunnelWrapper() { | ||||||
|     -webkit-border-radius: 0.2em; | 
 | ||||||
|     -khtml-border-radius: 0.2em; |     /** | ||||||
|     border-radius: 0.2em; |      * Wrapper for ActiveTunnel which adds display-specific | ||||||
| } |      * properties, such as a checked option. | ||||||
|  |      *  | ||||||
|  |      * @constructor | ||||||
|  |      * @param {ActiveTunnel} activeTunnel | ||||||
|  |      *     The ActiveTunnel to wrap. | ||||||
|  |      */ | ||||||
|  |     var ActiveTunnelWrapper = function ActiveTunnelWrapper(activeTunnel) { | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * The wrapped ActiveTunnel. | ||||||
|  |          * | ||||||
|  |          * @type ActiveTunnel | ||||||
|  |          */ | ||||||
|  |         this.tunnel = activeTunnel; | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * A flag indicating that the tunnel has been selected. | ||||||
|  |          * | ||||||
|  |          * @type Boolean | ||||||
|  |          */ | ||||||
|  |         this.checked = false; | ||||||
|  | 
 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return ActiveTunnelWrapper; | ||||||
|  | 
 | ||||||
|  | }]); | ||||||
| @@ -89,23 +89,64 @@ angular.module('userMenu').directive('guacUserMenu', [function guacUserMenu() { | |||||||
|             $scope.homeDisabled = ($location.path() === '/'); |             $scope.homeDisabled = ($location.path() === '/'); | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Whether the option to go to the management interface is |              * Whether the option to go to the user management interface is | ||||||
|              * disabled. Note that shis is different from canManageGuacamole, |              * disabled. Note that shis is different from canManageUsers, | ||||||
|              * which deals with whether permission to manage is granted. A user |              * which deals with whether permission to manage is granted. A user | ||||||
|              * may have permission, yet see this option as currently disabled. |              * may have permission, yet see this option as currently disabled. | ||||||
|              * |              * | ||||||
|              * @type Boolean |              * @type Boolean | ||||||
|              */ |              */ | ||||||
|             $scope.manageDisabled = ($location.path() === '/manage/'); |             $scope.manageUsersDisabled =  | ||||||
|  |                     ($location.path() === '/manage/modules/user'); | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Whether the current user has sufficient permissions to use the |              * Whether the option to go to the connection management interface is | ||||||
|              * management interface. If permissions have not yet been loaded, |              * disabled. Note that shis is different from canManageConnections, | ||||||
|              * this will be null. |              * which deals with whether permission to manage is granted. A user | ||||||
|  |              * may have permission, yet see this option as currently disabled. | ||||||
|              * |              * | ||||||
|              * @type Boolean |              * @type Boolean | ||||||
|              */ |              */ | ||||||
|             $scope.canManageGuacamole = null; |             $scope.manageConnectionsDisabled =  | ||||||
|  |                     ($location.path() === '/manage/modules/connections'); | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the option to go to the session management interface is | ||||||
|  |              * disabled. Note that shis is different from canManageConnections, | ||||||
|  |              * which deals with whether permission to manage is granted. A user | ||||||
|  |              * may have permission, yet see this option as currently disabled. | ||||||
|  |              * | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             $scope.manageSessionsDisabled =  | ||||||
|  |                     ($location.path() === '/manage/modules/sessions'); | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the current user has sufficient permissions to use the | ||||||
|  |              * user management interface. If permissions have not yet been  | ||||||
|  |              * loaded, this will be null. | ||||||
|  |              * | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             $scope.canManageUsers = null; | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the current user has sufficient permissions to use the | ||||||
|  |              * connection management interface. If permissions have not yet been  | ||||||
|  |              * loaded, this will be null. | ||||||
|  |              * | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             $scope.canManageConnections = null; | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the current user has sufficient permissions to use the | ||||||
|  |              * session management interface. If permissions have not yet been  | ||||||
|  |              * loaded, this will be null. | ||||||
|  |              * | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             $scope.canManageSessions = null; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Whether the current user has sufficient permissions to change |              * Whether the current user has sufficient permissions to change | ||||||
| @@ -173,29 +214,46 @@ angular.module('userMenu').directive('guacUserMenu', [function guacUserMenu() { | |||||||
|                 // Ignore permission to update self |                 // Ignore permission to update self | ||||||
|                 PermissionSet.removeUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, $scope.username); |                 PermissionSet.removeUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, $scope.username); | ||||||
|  |  | ||||||
|                 // Determine whether the current user needs access to the management UI |                 // Determine whether the current user needs access to the user management UI | ||||||
|                 $scope.canManageGuacamole = |                 $scope.canManageUsers = | ||||||
|  |  | ||||||
|                         // System permissions |                         // System permissions | ||||||
|                            PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) |                            PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||||
|                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_USER) |                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_USER) | ||||||
|  |  | ||||||
|  |                         // Permission to update users | ||||||
|  |                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.UPDATE) | ||||||
|  |  | ||||||
|  |                         // Permission to delete users | ||||||
|  |                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.DELETE) | ||||||
|  |  | ||||||
|  |                         // Permission to administer users | ||||||
|  |                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.ADMINISTER); | ||||||
|  |  | ||||||
|  |                 // Determine whether the current user needs access to the connection management UI | ||||||
|  |                 $scope.canManageConnections = | ||||||
|  |  | ||||||
|  |                         // System permissions | ||||||
|  |                            PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||||
|                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION) |                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION) | ||||||
|                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP) |                         || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP) | ||||||
|  |  | ||||||
|                         // Permission to update objects |                         // Permission to update connections or connection groups | ||||||
|                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.UPDATE) |                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.UPDATE) | ||||||
|                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE) |                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE) | ||||||
|                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.UPDATE) |  | ||||||
|  |  | ||||||
|                         // Permission to delete objects |                         // Permission to delete connections or connection groups | ||||||
|                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.DELETE) |                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.DELETE) | ||||||
|                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE) |                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE) | ||||||
|                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.DELETE) |  | ||||||
|  |  | ||||||
|                         // Permission to administer objects |                         // Permission to administer connections or connection groups | ||||||
|                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.ADMINISTER) |                         || PermissionSet.hasConnectionPermission(permissions,      PermissionSet.ObjectPermissionType.ADMINISTER) | ||||||
|                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER) |                         || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER); | ||||||
|                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.ADMINISTER); |                  | ||||||
|  |                 $scope.canManageSessions =  | ||||||
|  |                          | ||||||
|  |                         // A user must be a system administrator to manage sessions | ||||||
|  |                         PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER); | ||||||
|                  |                  | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
| @@ -289,10 +347,24 @@ angular.module('userMenu').directive('guacUserMenu', [function guacUserMenu() { | |||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Navigates to the management interface. |              * Navigates to the user management interface. | ||||||
|              */ |              */ | ||||||
|             $scope.manage = function manage() { |             $scope.manageUsers = function manageUsers() { | ||||||
|                 $location.path('/manage/'); |                 $location.path('/manage/modules/users'); | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Navigates to the connection management interface. | ||||||
|  |              */ | ||||||
|  |             $scope.manageConnections = function manageConnections() { | ||||||
|  |                 $location.path('/manage/modules/connections'); | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Navigates to the user session management interface. | ||||||
|  |              */ | ||||||
|  |             $scope.manageSessions = function manageSessions() { | ||||||
|  |                 $location.path('/manage/modules/sessions'); | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ | |||||||
|  |  | ||||||
|     cursor: default; |     cursor: default; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     min-width: 1.75in; |     min-width: 2in; | ||||||
|  |  | ||||||
|     font-size: 1.25em; |     font-size: 1.25em; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
| @@ -180,7 +180,9 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| .user-menu .options li a.home, | .user-menu .options li a.home, | ||||||
| .user-menu .options li a.manage, | .user-menu .options li a.manage-users, | ||||||
|  | .user-menu .options li a.manage-connections, | ||||||
|  | .user-menu .options li a.manage-sessions, | ||||||
| .user-menu .options li a.change-password, | .user-menu .options li a.change-password, | ||||||
| .user-menu .options li a.logout { | .user-menu .options li a.logout { | ||||||
|     background-repeat: no-repeat; |     background-repeat: no-repeat; | ||||||
| @@ -193,8 +195,16 @@ | |||||||
|     background-image: url('images/action-icons/guac-home-dark.png'); |     background-image: url('images/action-icons/guac-home-dark.png'); | ||||||
| } | } | ||||||
|  |  | ||||||
| .user-menu .options li a.manage { | .user-menu .options li a.manage-users { | ||||||
|     background-image: url('images/action-icons/guac-config-dark.png'); |     background-image: url('images/user-icons/guac-user.png'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .user-menu .options li a.manage-connections { | ||||||
|  |     background-image: url('images/protocol-icons/guac-monitor.png'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .user-menu .options li a.manage-sessions { | ||||||
|  |     background-image: url('images/protocol-icons/guac-plug.png'); | ||||||
| } | } | ||||||
|  |  | ||||||
| .user-menu .options li a.change-password { | .user-menu .options li a.change-password { | ||||||
|   | |||||||
| @@ -35,10 +35,24 @@ | |||||||
|                 </a> |                 </a> | ||||||
|             </li> |             </li> | ||||||
|  |  | ||||||
|             <!-- Manage --> |             <!-- Manage Users --> | ||||||
|             <li> |             <li> | ||||||
|                 <a class="manage" ng-click="manage()" ng-class="{disabled: manageDisabled}" ng-show="canManageGuacamole" href="#/manage/"> |                 <a class="manage-users" ng-click="manageUsers()" ng-class="{disabled: manageUsersDisabled}" ng-show="canManageUsers" href="#/manage/modules/users"> | ||||||
|                     {{'USER_MENU.ACTION_MANAGE' | translate}} |                     {{'USER_MENU.ACTION_MANAGE_USERS' | translate}} | ||||||
|  |                 </a> | ||||||
|  |             </li> | ||||||
|  |  | ||||||
|  |             <!-- Manage Connections --> | ||||||
|  |             <li> | ||||||
|  |                 <a class="manage-connections" ng-click="manageConnections()" ng-class="{disabled: manageConnectionsDisabled}" ng-show="canManageConnections" href="#/manage/modules/connections"> | ||||||
|  |                     {{'USER_MENU.ACTION_MANAGE_CONNECTIONS' | translate}} | ||||||
|  |                 </a> | ||||||
|  |             </li> | ||||||
|  |  | ||||||
|  |             <!-- Manage Sessions --> | ||||||
|  |             <li> | ||||||
|  |                 <a class="manage-sessions" ng-click="manageSessions()" ng-class="{disabled: manageSessionsDisabled}" ng-show="canManageSessions" href="#/manage/modules/sessions"> | ||||||
|  |                     {{'USER_MENU.ACTION_MANAGE_SESSIONS' | translate}} | ||||||
|                 </a> |                 </a> | ||||||
|             </li> |             </li> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,9 +7,12 @@ | |||||||
|         "ACTION_CHANGE_PASSWORD"    : "Change Password", |         "ACTION_CHANGE_PASSWORD"    : "Change Password", | ||||||
|         "ACTION_CLONE"              : "Clone", |         "ACTION_CLONE"              : "Clone", | ||||||
|         "ACTION_DELETE"             : "Delete", |         "ACTION_DELETE"             : "Delete", | ||||||
|  |         "ACTION_DELETE_SESSIONS"    : "Kill Sessions", | ||||||
|         "ACTION_LOGIN"              : "Login", |         "ACTION_LOGIN"              : "Login", | ||||||
|         "ACTION_LOGOUT"             : "Logout", |         "ACTION_LOGOUT"             : "Logout", | ||||||
|         "ACTION_MANAGE"          : "Manage", |         "ACTION_MANAGE_CONNECTIONS" : "Manage Connections", | ||||||
|  |         "ACTION_MANAGE_SESSIONS"    : "Manage Sessions", | ||||||
|  |         "ACTION_MANAGE_USERS"       : "Manage Users", | ||||||
|         "ACTION_NAVIGATE_BACK"      : "Back", |         "ACTION_NAVIGATE_BACK"      : "Back", | ||||||
|         "ACTION_NAVIGATE_HOME"      : "Home", |         "ACTION_NAVIGATE_HOME"      : "Home", | ||||||
|         "ACTION_SAVE"               : "Save", |         "ACTION_SAVE"               : "Save", | ||||||
| @@ -136,34 +139,14 @@ | |||||||
|  |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     "MANAGE" : { |  | ||||||
|  |  | ||||||
|         "ACTION_ACKNOWLEDGE"          : "@:APP.ACTION_ACKNOWLEDGE", |  | ||||||
|         "ACTION_NEW_USER"             : "New User", |  | ||||||
|         "ACTION_NEW_CONNECTION"       : "New Connection", |  | ||||||
|         "ACTION_NEW_CONNECTION_GROUP" : "New Group", |  | ||||||
|  |  | ||||||
|         "DIALOG_HEADER_ERROR"           : "Error", |  | ||||||
|  |  | ||||||
|         "HELP_CONNECTIONS"   : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.", |  | ||||||
|         "HELP_SHOW_PASSWORD" : "Click to show password", |  | ||||||
|         "HELP_HIDE_PASSWORD" : "Click to hide password", |  | ||||||
|         "HELP_USERS"         : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.", |  | ||||||
|          |  | ||||||
|         "INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT", |  | ||||||
|  |  | ||||||
|         "SECTION_HEADER_ADMINISTRATION" : "Administration", |  | ||||||
|         "SECTION_HEADER_CONNECTIONS"    : "Connections", |  | ||||||
|         "SECTION_HEADER_USERS"          : "Users" |  | ||||||
|  |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     "MANAGE_CONNECTION" : { |     "MANAGE_CONNECTION" : { | ||||||
|  |  | ||||||
|         "ACTION_ACKNOWLEDGE"          : "@:APP.ACTION_ACKNOWLEDGE", |         "ACTION_ACKNOWLEDGE"          : "@:APP.ACTION_ACKNOWLEDGE", | ||||||
|         "ACTION_CANCEL"               : "@:APP.ACTION_CANCEL", |         "ACTION_CANCEL"               : "@:APP.ACTION_CANCEL", | ||||||
|         "ACTION_CLONE"                : "@:APP.ACTION_CLONE", |         "ACTION_CLONE"                : "@:APP.ACTION_CLONE", | ||||||
|         "ACTION_DELETE"               : "@:APP.ACTION_DELETE", |         "ACTION_DELETE"               : "@:APP.ACTION_DELETE", | ||||||
|  |         "ACTION_NEW_CONNECTION"       : "New Connection", | ||||||
|  |         "ACTION_NEW_CONNECTION_GROUP" : "New Group", | ||||||
|         "ACTION_SAVE"                 : "@:APP.ACTION_SAVE", |         "ACTION_SAVE"                 : "@:APP.ACTION_SAVE", | ||||||
|  |  | ||||||
|         "DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection", |         "DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection", | ||||||
| @@ -173,10 +156,16 @@ | |||||||
|         "FIELD_HEADER_NAME"     : "Name:", |         "FIELD_HEADER_NAME"     : "Name:", | ||||||
|         "FIELD_HEADER_PROTOCOL" : "Protocol:", |         "FIELD_HEADER_PROTOCOL" : "Protocol:", | ||||||
|          |          | ||||||
|  |         "HELP_CONNECTIONS"   : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.", | ||||||
|  |         "HELP_SHOW_PASSWORD" : "Click to show password", | ||||||
|  |         "HELP_HIDE_PASSWORD" : "Click to hide password", | ||||||
|  |          | ||||||
|  |         "INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT", | ||||||
|         "INFO_CONNECTION_DURATION_UNKNOWN" : "--", |         "INFO_CONNECTION_DURATION_UNKNOWN" : "--", | ||||||
|         "INFO_CONNECTION_ACTIVE_NOW"       : "Active Now", |         "INFO_CONNECTION_ACTIVE_NOW"       : "Active Now", | ||||||
|         "INFO_CONNECTION_NOT_USED"         : "This connection has not yet been used.", |         "INFO_CONNECTION_NOT_USED"         : "This connection has not yet been used.", | ||||||
|  |  | ||||||
|  |         "SECTION_HEADER_CONNECTIONS"     : "Connections", | ||||||
|         "SECTION_HEADER_EDIT_CONNECTION" : "Edit Connection", |         "SECTION_HEADER_EDIT_CONNECTION" : "Edit Connection", | ||||||
|         "SECTION_HEADER_HISTORY"         : "Usage History", |         "SECTION_HEADER_HISTORY"         : "Usage History", | ||||||
|         "SECTION_HEADER_PARAMETERS"      : "Parameters", |         "SECTION_HEADER_PARAMETERS"      : "Parameters", | ||||||
| @@ -218,6 +207,7 @@ | |||||||
|         "ACTION_ACKNOWLEDGE"   : "@:APP.ACTION_ACKNOWLEDGE", |         "ACTION_ACKNOWLEDGE"   : "@:APP.ACTION_ACKNOWLEDGE", | ||||||
|         "ACTION_CANCEL"        : "@:APP.ACTION_CANCEL", |         "ACTION_CANCEL"        : "@:APP.ACTION_CANCEL", | ||||||
|         "ACTION_DELETE"        : "@:APP.ACTION_DELETE", |         "ACTION_DELETE"        : "@:APP.ACTION_DELETE", | ||||||
|  |         "ACTION_NEW_USER"      : "New User", | ||||||
|         "ACTION_SAVE"          : "@:APP.ACTION_SAVE", |         "ACTION_SAVE"          : "@:APP.ACTION_SAVE", | ||||||
|  |  | ||||||
|         "DIALOG_HEADER_CONFIRM_DELETE"  : "Delete User", |         "DIALOG_HEADER_CONFIRM_DELETE"  : "Delete User", | ||||||
| @@ -233,14 +223,37 @@ | |||||||
|         "FIELD_HEADER_PASSWORD_AGAIN"                : "@:APP.FIELD_HEADER_PASSWORD_AGAIN", |         "FIELD_HEADER_PASSWORD_AGAIN"                : "@:APP.FIELD_HEADER_PASSWORD_AGAIN", | ||||||
|         "FIELD_HEADER_USERNAME"                      : "Username:", |         "FIELD_HEADER_USERNAME"                      : "Username:", | ||||||
|          |          | ||||||
|  |         "HELP_USERS" : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.", | ||||||
|  |  | ||||||
|         "SECTION_HEADER_CONNECTIONS" : "Connections", |         "SECTION_HEADER_CONNECTIONS" : "Connections", | ||||||
|         "SECTION_HEADER_EDIT_USER"   : "Edit User", |         "SECTION_HEADER_EDIT_USER"   : "Edit User", | ||||||
|         "SECTION_HEADER_PERMISSIONS" : "Permissions", |         "SECTION_HEADER_PERMISSIONS" : "Permissions", | ||||||
|  |         "SECTION_HEADER_USERS"       : "Users", | ||||||
|  |  | ||||||
|         "TEXT_CONFIRM_DELETE" : "Users cannot be restored after they have been deleted. Are you sure you want to delete this user?" |         "TEXT_CONFIRM_DELETE" : "Users cannot be restored after they have been deleted. Are you sure you want to delete this user?" | ||||||
|  |  | ||||||
|     }, |     }, | ||||||
|      |      | ||||||
|  |     "MANAGE_SESSION" : { | ||||||
|  |          | ||||||
|  |         "ACTION_DELETE" : "Kill all selected sessions", | ||||||
|  |          | ||||||
|  |         "DIALOG_HEADER_CONFIRM_DELETE" : "Kill Sessions", | ||||||
|  |         "DIALOG_HEADER_ERROR"          : "Error", | ||||||
|  |          | ||||||
|  |         "HELP_SESSIONS" : "Click to kill a user session.", | ||||||
|  |          | ||||||
|  |         "SECTION_HEADER_SESSIONS" : "Sessions", | ||||||
|  |          | ||||||
|  |         "TABLE_HEADER_SESSION_USERNAME"        : "Username", | ||||||
|  |         "TABLE_HEADER_SESSION_STARTDATE"       : "Start date", | ||||||
|  |         "TABLE_HEADER_SESSION_REMOTEHOST"      : "Remote host", | ||||||
|  |         "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Connection name", | ||||||
|  |          | ||||||
|  |         "TEXT_CONFIRM_DELETE" : "Are you sure you want to kill these sessions?" | ||||||
|  |  | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     "PROTOCOL_RDP" : { |     "PROTOCOL_RDP" : { | ||||||
|  |  | ||||||
|         "FIELD_HEADER_COLOR_DEPTH"     : "Color depth:", |         "FIELD_HEADER_COLOR_DEPTH"     : "Color depth:", | ||||||
| @@ -387,7 +400,9 @@ | |||||||
|         "ACTION_CANCEL"             : "@:APP.ACTION_CANCEL", |         "ACTION_CANCEL"             : "@:APP.ACTION_CANCEL", | ||||||
|         "ACTION_CHANGE_PASSWORD"    : "@:APP.ACTION_CHANGE_PASSWORD", |         "ACTION_CHANGE_PASSWORD"    : "@:APP.ACTION_CHANGE_PASSWORD", | ||||||
|         "ACTION_LOGOUT"             : "@:APP.ACTION_LOGOUT", |         "ACTION_LOGOUT"             : "@:APP.ACTION_LOGOUT", | ||||||
|         "ACTION_MANAGE"          : "@:APP.ACTION_MANAGE", |         "ACTION_MANAGE_CONNECTIONS" : "@:APP.ACTION_MANAGE_CONNECTIONS", | ||||||
|  |         "ACTION_MANAGE_SESSIONS"    : "@:APP.ACTION_MANAGE_SESSIONS", | ||||||
|  |         "ACTION_MANAGE_USERS"       : "@:APP.ACTION_MANAGE_USERS", | ||||||
|         "ACTION_NAVIGATE_HOME"      : "@:APP.ACTION_NAVIGATE_HOME", |         "ACTION_NAVIGATE_HOME"      : "@:APP.ACTION_NAVIGATE_HOME", | ||||||
|         "ACTION_SAVE"               : "@:APP.ACTION_SAVE", |         "ACTION_SAVE"               : "@:APP.ACTION_SAVE", | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user