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 } | ||||
|         }) | ||||
|  | ||||
|         // Management screen | ||||
|         .when('/manage/', { | ||||
|         // Connection management screen | ||||
|         .when('/manage/modules/connections/', { | ||||
|             title         : 'APP.NAME', | ||||
|             bodyClassName : 'manage', | ||||
|             templateUrl   : 'app/manage/templates/manage.html', | ||||
|             controller    : 'manageController', | ||||
|             templateUrl   : 'app/manage/templates/manageConnections.html', | ||||
|             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 } | ||||
|         }) | ||||
|  | ||||
|   | ||||
| @@ -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',  | ||||
|         function manageController($scope, $injector) { | ||||
| angular.module('manage').controller('manageConnectionsController', ['$scope', '$injector',  | ||||
|         function manageConnectionsController($scope, $injector) { | ||||
| 
 | ||||
|     // Required types
 | ||||
|     var ConnectionGroup = $injector.get('ConnectionGroup'); | ||||
|     var PermissionSet   = $injector.get('PermissionSet'); | ||||
|     var User            = $injector.get('User'); | ||||
| 
 | ||||
|     // Required services
 | ||||
|     var $location              = $injector.get('$location'); | ||||
| @@ -37,7 +36,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|     var connectionGroupService = $injector.get('connectionGroupService'); | ||||
|     var guacNotification       = $injector.get('guacNotification'); | ||||
|     var permissionService      = $injector.get('permissionService'); | ||||
|     var userService            = $injector.get('userService'); | ||||
| 
 | ||||
|     // Identifier of the current user
 | ||||
|     var currentUserID = authenticationService.getCurrentUserID(); | ||||
| @@ -47,20 +45,13 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|      * closes the currently-shown status dialog. | ||||
|      */ | ||||
|     var ACKNOWLEDGE_ACTION = { | ||||
|         name        : "MANAGE.ACTION_ACKNOWLEDGE", | ||||
|         name        : "MANAGE_CONNECTION.ACTION_ACKNOWLEDGE", | ||||
|         // Handle action
 | ||||
|         callback    : function acknowledgeCallback() { | ||||
|             guacNotification.showStatus(false); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * All visible users. | ||||
|      * | ||||
|      * @type User[] | ||||
|      */ | ||||
|     $scope.users = null; | ||||
| 
 | ||||
|     /** | ||||
|      * The root connection group of the connection group hierarchy. | ||||
|      * | ||||
| @@ -68,14 +59,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|      */ | ||||
|     $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 | ||||
|      * permissions have not yet been loaded, this will be null. | ||||
| @@ -84,14 +67,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|      */ | ||||
|     $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 | ||||
|      * permissions have not yet been loaded, this will be null. | ||||
| @@ -108,14 +83,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|      */ | ||||
|     $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 | ||||
|      * permissions have not yet been loaded. | ||||
| @@ -133,12 +100,9 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|      */ | ||||
|     $scope.isLoaded = function isLoaded() { | ||||
| 
 | ||||
|         return $scope.users                     !== null | ||||
|             && $scope.rootGroup                 !== null | ||||
|         return $scope.rootGroup                 !== null | ||||
|             && $scope.permissions               !== null | ||||
|             && $scope.canManageUsers            !== null | ||||
|             && $scope.canManageConnections      !== null | ||||
|             && $scope.canCreateUsers            !== null | ||||
|             && $scope.canCreateConnections      !== null | ||||
|             && $scope.canCreateConnectionGroups !== null; | ||||
| 
 | ||||
| @@ -153,11 +117,6 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|         // Ignore permission to update root group
 | ||||
|         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
 | ||||
|         $scope.canCreateConnections = | ||||
|                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.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
 | ||||
|         $scope.canManageConnections = | ||||
| 
 | ||||
| @@ -188,7 +141,7 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|             || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE); | ||||
| 
 | ||||
|         // Return to home if there's nothing to do here
 | ||||
|         if (!$scope.canManageUsers && !$scope.canManageConnections) | ||||
|         if (!$scope.canManageConnections) | ||||
|             $location.path('/'); | ||||
|          | ||||
|     }); | ||||
| @@ -200,50 +153,4 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | ||||
|         $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 | ||||
| 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="header"> | ||||
|         <h2>{{'MANAGE.SECTION_HEADER_ADMINISTRATION' | translate}}</h2> | ||||
|         <h2>{{'MANAGE_USER.SECTION_HEADER_USERS' | translate}}</h2> | ||||
|         <guac-user-menu permissions="permissions"></guac-user-menu> | ||||
|     </div> | ||||
| 
 | ||||
|     <!-- User management --> | ||||
|     <div class="settings section" ng-show="canManageUsers"> | ||||
|         <h3>{{'MANAGE.SECTION_HEADER_USERS' | translate}}</h3> | ||||
|         <div class="users"> | ||||
| 
 | ||||
|             <p>{{'MANAGE.HELP_USERS' | translate}}</p> | ||||
|             <p>{{'MANAGE_USER.HELP_USERS' | translate}}</p> | ||||
| 
 | ||||
|             <!-- User creation form --> | ||||
|             <div class="user-add-form" ng-show="canCreateUsers"> | ||||
|                 <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> | ||||
| 
 | ||||
|             <!-- List of users this user has access to --> | ||||
| @@ -53,39 +52,9 @@ THE SOFTWARE. | ||||
|             </div> | ||||
| 
 | ||||
|             <!-- 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> | ||||
| 
 | ||||
|     <!-- 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> | ||||
| @@ -20,12 +20,38 @@ | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| .manage .connection-list .group-list-page, | ||||
| .manage .user-list { | ||||
|     border: 1px solid rgba(0, 0, 0, 0.25); | ||||
|     min-height: 15em; | ||||
|     -moz-border-radius: 0.2em; | ||||
|     -webkit-border-radius: 0.2em; | ||||
|     -khtml-border-radius: 0.2em; | ||||
|     border-radius: 0.2em; | ||||
| } | ||||
| /** | ||||
|  * A service for defining the ActiveTunnelWrapper class. | ||||
|  */ | ||||
| angular.module('manage').factory('ActiveTunnelWrapper', [ | ||||
|     function defineActiveTunnelWrapper() { | ||||
| 
 | ||||
|     /** | ||||
|      * 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() === '/'); | ||||
|  | ||||
|             /** | ||||
|              * Whether the option to go to the management interface is | ||||
|              * disabled. Note that shis is different from canManageGuacamole, | ||||
|              * Whether the option to go to the user management interface is | ||||
|              * disabled. Note that shis is different from canManageUsers, | ||||
|              * which deals with whether permission to manage is granted. A user | ||||
|              * may have permission, yet see this option as currently disabled. | ||||
|              * | ||||
|              * @type Boolean | ||||
|              */ | ||||
|             $scope.manageDisabled = ($location.path() === '/manage/'); | ||||
|             $scope.manageUsersDisabled =  | ||||
|                     ($location.path() === '/manage/modules/user'); | ||||
|  | ||||
|             /** | ||||
|              * Whether the current user has sufficient permissions to use the | ||||
|              * management interface. If permissions have not yet been loaded, | ||||
|              * this will be null. | ||||
|              * Whether the option to go to the connection 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.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 | ||||
| @@ -173,29 +214,46 @@ angular.module('userMenu').directive('guacUserMenu', [function guacUserMenu() { | ||||
|                 // Ignore permission to update self | ||||
|                 PermissionSet.removeUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, $scope.username); | ||||
|  | ||||
|                 // Determine whether the current user needs access to the management UI | ||||
|                 $scope.canManageGuacamole = | ||||
|                 // Determine whether the current user needs access to the user management UI | ||||
|                 $scope.canManageUsers = | ||||
|  | ||||
|                         // System permissions | ||||
|                            PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) | ||||
|                         || 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_GROUP) | ||||
|  | ||||
|                         // Permission to update objects | ||||
|                         // Permission to update connections or connection groups | ||||
|                         || PermissionSet.hasConnectionPermission(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.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.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER) | ||||
|                         || PermissionSet.hasUserPermission(permissions,            PermissionSet.ObjectPermissionType.ADMINISTER); | ||||
|                         || PermissionSet.hasConnectionGroupPermission(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() { | ||||
|                 $location.path('/manage/'); | ||||
|             $scope.manageUsers = function manageUsers() { | ||||
|                 $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; | ||||
|     margin: 0; | ||||
|     min-width: 1.75in; | ||||
|     min-width: 2in; | ||||
|  | ||||
|     font-size: 1.25em; | ||||
|     font-weight: bold; | ||||
| @@ -180,7 +180,9 @@ | ||||
| } | ||||
|  | ||||
| .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.logout { | ||||
|     background-repeat: no-repeat; | ||||
| @@ -193,8 +195,16 @@ | ||||
|     background-image: url('images/action-icons/guac-home-dark.png'); | ||||
| } | ||||
|  | ||||
| .user-menu .options li a.manage { | ||||
|     background-image: url('images/action-icons/guac-config-dark.png'); | ||||
| .user-menu .options li a.manage-users { | ||||
|     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 { | ||||
|   | ||||
| @@ -35,10 +35,24 @@ | ||||
|                 </a> | ||||
|             </li> | ||||
|  | ||||
|             <!-- Manage --> | ||||
|             <!-- Manage Users --> | ||||
|             <li> | ||||
|                 <a class="manage" ng-click="manage()" ng-class="{disabled: manageDisabled}" ng-show="canManageGuacamole" href="#/manage/"> | ||||
|                     {{'USER_MENU.ACTION_MANAGE' | translate}} | ||||
|                 <a class="manage-users" ng-click="manageUsers()" ng-class="{disabled: manageUsersDisabled}" ng-show="canManageUsers" href="#/manage/modules/users"> | ||||
|                     {{'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> | ||||
|             </li> | ||||
|  | ||||
|   | ||||
| @@ -2,19 +2,22 @@ | ||||
|  | ||||
|     "APP" : { | ||||
|  | ||||
|         "ACTION_ACKNOWLEDGE"     : "OK", | ||||
|         "ACTION_CANCEL"          : "Cancel", | ||||
|         "ACTION_CHANGE_PASSWORD" : "Change Password", | ||||
|         "ACTION_CLONE"           : "Clone", | ||||
|         "ACTION_DELETE"          : "Delete", | ||||
|         "ACTION_LOGIN"           : "Login", | ||||
|         "ACTION_LOGOUT"          : "Logout", | ||||
|         "ACTION_MANAGE"          : "Manage", | ||||
|         "ACTION_NAVIGATE_BACK"   : "Back", | ||||
|         "ACTION_NAVIGATE_HOME"   : "Home", | ||||
|         "ACTION_SAVE"            : "Save", | ||||
|         "ACTION_ACKNOWLEDGE"        : "OK", | ||||
|         "ACTION_CANCEL"             : "Cancel", | ||||
|         "ACTION_CHANGE_PASSWORD"    : "Change Password", | ||||
|         "ACTION_CLONE"              : "Clone", | ||||
|         "ACTION_DELETE"             : "Delete", | ||||
|         "ACTION_DELETE_SESSIONS"    : "Kill Sessions", | ||||
|         "ACTION_LOGIN"              : "Login", | ||||
|         "ACTION_LOGOUT"             : "Logout", | ||||
|         "ACTION_MANAGE_CONNECTIONS" : "Manage Connections", | ||||
|         "ACTION_MANAGE_SESSIONS"    : "Manage Sessions", | ||||
|         "ACTION_MANAGE_USERS"       : "Manage Users", | ||||
|         "ACTION_NAVIGATE_BACK"      : "Back", | ||||
|         "ACTION_NAVIGATE_HOME"      : "Home", | ||||
|         "ACTION_SAVE"               : "Save", | ||||
|  | ||||
|         "DIALOG_HEADER_ERROR"    : "Error", | ||||
|         "DIALOG_HEADER_ERROR" : "Error", | ||||
|  | ||||
|         "ERROR_PASSWORD_MISMATCH" : "The provided passwords do not match.", | ||||
|          | ||||
| @@ -136,35 +139,15 @@ | ||||
|  | ||||
|     }, | ||||
|  | ||||
|     "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" : { | ||||
|  | ||||
|         "ACTION_ACKNOWLEDGE"   : "@:APP.ACTION_ACKNOWLEDGE", | ||||
|         "ACTION_CANCEL"        : "@:APP.ACTION_CANCEL", | ||||
|         "ACTION_CLONE"         : "@:APP.ACTION_CLONE", | ||||
|         "ACTION_DELETE"        : "@:APP.ACTION_DELETE", | ||||
|         "ACTION_SAVE"          : "@:APP.ACTION_SAVE", | ||||
|         "ACTION_ACKNOWLEDGE"          : "@:APP.ACTION_ACKNOWLEDGE", | ||||
|         "ACTION_CANCEL"               : "@:APP.ACTION_CANCEL", | ||||
|         "ACTION_CLONE"                : "@:APP.ACTION_CLONE", | ||||
|         "ACTION_DELETE"               : "@:APP.ACTION_DELETE", | ||||
|         "ACTION_NEW_CONNECTION"       : "New Connection", | ||||
|         "ACTION_NEW_CONNECTION_GROUP" : "New Group", | ||||
|         "ACTION_SAVE"                 : "@:APP.ACTION_SAVE", | ||||
|  | ||||
|         "DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection", | ||||
|         "DIALOG_HEADER_ERROR"          : "Error", | ||||
| @@ -173,10 +156,16 @@ | ||||
|         "FIELD_HEADER_NAME"     : "Name:", | ||||
|         "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_ACTIVE_NOW"       : "Active Now", | ||||
|         "INFO_CONNECTION_NOT_USED"         : "This connection has not yet been used.", | ||||
|  | ||||
|         "SECTION_HEADER_CONNECTIONS"     : "Connections", | ||||
|         "SECTION_HEADER_EDIT_CONNECTION" : "Edit Connection", | ||||
|         "SECTION_HEADER_HISTORY"         : "Usage History", | ||||
|         "SECTION_HEADER_PARAMETERS"      : "Parameters", | ||||
| @@ -218,6 +207,7 @@ | ||||
|         "ACTION_ACKNOWLEDGE"   : "@:APP.ACTION_ACKNOWLEDGE", | ||||
|         "ACTION_CANCEL"        : "@:APP.ACTION_CANCEL", | ||||
|         "ACTION_DELETE"        : "@:APP.ACTION_DELETE", | ||||
|         "ACTION_NEW_USER"      : "New User", | ||||
|         "ACTION_SAVE"          : "@:APP.ACTION_SAVE", | ||||
|  | ||||
|         "DIALOG_HEADER_CONFIRM_DELETE"  : "Delete User", | ||||
| @@ -233,14 +223,37 @@ | ||||
|         "FIELD_HEADER_PASSWORD_AGAIN"                : "@:APP.FIELD_HEADER_PASSWORD_AGAIN", | ||||
|         "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_EDIT_USER"   : "Edit User", | ||||
|         "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?" | ||||
|  | ||||
|     }, | ||||
|      | ||||
|     "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" : { | ||||
|  | ||||
|         "FIELD_HEADER_COLOR_DEPTH"     : "Color depth:", | ||||
| @@ -383,13 +396,15 @@ | ||||
|  | ||||
|     "USER_MENU" : { | ||||
|  | ||||
|         "ACTION_ACKNOWLEDGE"     : "@:APP.ACTION_ACKNOWLEDGE", | ||||
|         "ACTION_CANCEL"          : "@:APP.ACTION_CANCEL", | ||||
|         "ACTION_CHANGE_PASSWORD" : "@:APP.ACTION_CHANGE_PASSWORD", | ||||
|         "ACTION_LOGOUT"          : "@:APP.ACTION_LOGOUT", | ||||
|         "ACTION_MANAGE"          : "@:APP.ACTION_MANAGE", | ||||
|         "ACTION_NAVIGATE_HOME"   : "@:APP.ACTION_NAVIGATE_HOME", | ||||
|         "ACTION_SAVE"            : "@:APP.ACTION_SAVE", | ||||
|         "ACTION_ACKNOWLEDGE"        : "@:APP.ACTION_ACKNOWLEDGE", | ||||
|         "ACTION_CANCEL"             : "@:APP.ACTION_CANCEL", | ||||
|         "ACTION_CHANGE_PASSWORD"    : "@:APP.ACTION_CHANGE_PASSWORD", | ||||
|         "ACTION_LOGOUT"             : "@:APP.ACTION_LOGOUT", | ||||
|         "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_SAVE"               : "@:APP.ACTION_SAVE", | ||||
|  | ||||
|         "DIALOG_HEADER_ERROR"    : "@:APP.DIALOG_HEADER_ERROR", | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user