GUAC-1133 Split out session, user, and connection manage pages, rudimentary session management interface.

This commit is contained in:
James Muehlner
2015-03-17 23:19:21 -07:00
parent 803d85f4b5
commit 06b68a6834
12 changed files with 791 additions and 221 deletions

View File

@@ -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('/');
});
@@ -199,51 +152,5 @@ angular.module('manage').controller('manageController', ['$scope', '$injector',
.success(function connectionGroupReceived(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 = "";
};
}]);

View File

@@ -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--;
};
}]);

View File

@@ -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 = "";
};
}]);