You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/05/04 08:26:55 UTC
[01/21] guacamole-client git commit: GUACAMOLE-220: Separate
system/connection permission editing into directives.
Repository: guacamole-client
Updated Branches:
refs/heads/master 91f19b2e0 -> 9b99b1804
GUACAMOLE-220: Separate system/connection permission editing into directives.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/94ad1f9f
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/94ad1f9f
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/94ad1f9f
Branch: refs/heads/master
Commit: 94ad1f9f349826ede932ea843ed87f58cc76d598
Parents: 8181a96
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 28 23:05:27 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Apr 30 14:43:54 2018 -0700
----------------------------------------------------------------------
.../manage/controllers/manageUserController.js | 580 ++-----------------
.../directives/connectionPermissionEditor.js | 406 +++++++++++++
.../manage/directives/systemPermissionEditor.js | 308 ++++++++++
.../templates/connectionPermissionEditor.html | 21 +
.../webapp/app/manage/templates/manageUser.html | 52 +-
.../templates/systemPermissionEditor.html | 18 +
6 files changed, 809 insertions(+), 576 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index eae141b..c385065 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -24,8 +24,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
function manageUserController($scope, $injector) {
// Required types
- var ConnectionGroup = $injector.get('ConnectionGroup');
- var GroupListItem = $injector.get('GroupListItem');
var PageDefinition = $injector.get('PageDefinition');
var PermissionFlagSet = $injector.get('PermissionFlagSet');
var PermissionSet = $injector.get('PermissionSet');
@@ -35,7 +33,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var $location = $injector.get('$location');
var $routeParams = $injector.get('$routeParams');
var authenticationService = $injector.get('authenticationService');
- var connectionGroupService = $injector.get('connectionGroupService');
var dataSourceService = $injector.get('dataSourceService');
var guacNotification = $injector.get('guacNotification');
var permissionService = $injector.get('permissionService');
@@ -72,14 +69,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var currentUsername = authenticationService.getCurrentUsername();
/**
- * The unique identifier of the data source containing the user being
- * edited.
- *
- * @type String
- */
- var selectedDataSource = $routeParams.dataSource;
-
- /**
* The username of the original user from which this user is
* being cloned. Only valid if this is a new user.
*
@@ -96,6 +85,14 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var username = $routeParams.id;
/**
+ * The unique identifier of the data source containing the user being
+ * edited.
+ *
+ * @type String
+ */
+ $scope.dataSource = $routeParams.dataSource;
+
+ /**
* The string value representing the user currently being edited within the
* permission flag set. Note that his may not match the user's actual
* username - it is a marker that is (1) guaranteed to be associated with
@@ -131,34 +128,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.permissionFlags = null;
/**
- * A map of data source identifiers to the root connection groups within
- * thost data sources. As only one data source is applicable to any one
- * user being edited/created, this will only contain a single key.
- *
- * @type Object.<String, GroupListItem>
- */
- $scope.rootGroups = null;
-
- /**
- * Array of all connection properties that are filterable.
- *
- * @type String[]
- */
- $scope.filteredConnectionProperties = [
- 'name',
- 'protocol'
- ];
-
- /**
- * Array of all connection group properties that are filterable.
- *
- * @type String[]
- */
- $scope.filteredConnectionGroupProperties = [
- 'name'
- ];
-
- /**
* A map of data source identifiers to the set of all permissions
* associated with the current user under that data source, or null if the
* user's permissions have not yet been loaded.
@@ -219,7 +188,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// Account exists only if it was successfully retrieved
return (dataSource in $scope.users);
@@ -245,7 +214,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// Attributes can always be set if we are creating the user
if (!$scope.userExists(dataSource))
@@ -275,7 +244,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.canChangeAllAttributes = function canChangeAllAttributes() {
// All attributes can be set if we are creating the user
- return !$scope.userExists(selectedDataSource);
+ return !$scope.userExists($scope.dataSource);
};
@@ -299,7 +268,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// Permissions can always be set if we are creating the user
if (!$scope.userExists(dataSource))
@@ -318,33 +287,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Returns whether the current user can change the system permissions
- * granted to the user being edited within the given data source.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
- *
- * @returns {Boolean}
- * true if the current user can grant or revoke system permissions to
- * the user being edited, false otherwise.
- */
- $scope.canChangeSystemPermissions = function canChangeSystemPermissions(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
-
- // Only the administrator can modify system permissions
- return PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER);
-
- };
-
- /**
* Returns whether the current user can edit the username of the user being
* edited within the given data source.
*
@@ -380,7 +322,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// The administrator can always save users
if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
@@ -417,10 +359,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// If we are not editing an existing user, we cannot clone
- if (!$scope.userExists(selectedDataSource))
+ if (!$scope.userExists($scope.dataSource))
return false;
// The administrator can always clone users
@@ -453,7 +395,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return false;
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// Can't delete what doesn't exist
if (!$scope.userExists(dataSource))
@@ -485,7 +427,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.isReadOnly = function isReadOnly(dataSource) {
// Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
+ dataSource = dataSource || $scope.dataSource;
// User is read-only if they cannot be saved
return !$scope.canSaveUser(dataSource);
@@ -509,7 +451,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
return;
// Only the selected data source is relevant when cloning
- if (cloneSourceUsername && dataSource !== selectedDataSource)
+ if (cloneSourceUsername && dataSource !== $scope.dataSource)
return;
// Determine class name based on read-only / linked status
@@ -530,7 +472,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
});
// Pull user attribute schema
- schemaService.getUserAttributes(selectedDataSource).then(function attributesReceived(attributes) {
+ schemaService.getUserAttributes($scope.dataSource).then(function attributesReceived(attributes) {
$scope.attributes = attributes;
}, requestService.WARN);
@@ -543,7 +485,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Get user for currently-selected data source
$scope.users = users;
- $scope.user = users[selectedDataSource];
+ $scope.user = users[$scope.dataSource];
// Create skeleton user if user does not exist
if (!$scope.user)
@@ -558,7 +500,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.selfUsername = username;
// Pull user permissions
- permissionService.getPermissions(selectedDataSource, username).then(function gotPermissions(permissions) {
+ permissionService.getPermissions($scope.dataSource, username).then(function gotPermissions(permissions) {
$scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
})
@@ -576,7 +518,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Get user for currently-selected data source
$scope.users = {};
- $scope.user = users[selectedDataSource];
+ $scope.user = users[$scope.dataSource];
}, requestService.WARN);
@@ -585,10 +527,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.selfUsername = cloneSourceUsername;
// Pull user permissions
- permissionService.getPermissions(selectedDataSource, cloneSourceUsername)
+ permissionService.getPermissions($scope.dataSource, cloneSourceUsername)
.then(function gotPermissions(permissions) {
$scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
- permissionsAdded = permissions;
+ $scope.permissionsAdded = permissions;
})
// If permissions cannot be retrieved, use empty permissions
@@ -607,78 +549,13 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.user = new User();
$scope.permissionFlags = new PermissionFlagSet();
- }
+ // As no permissions are yet associated with the user, it is safe to
+ // use any non-empty username as a placeholder for self-referential
+ // permissions
+ $scope.selfUsername = 'SELF';
- /**
- * Expands all items within the tree descending from the given
- * GroupListItem which have at least one descendant for which explicit READ
- * permission is granted. The expanded state of all other items is left
- * untouched.
- *
- * @param {GroupListItem} item
- * The GroupListItem which should be conditionally expanded depending
- * on whether READ permission is granted for any of its descendants.
- *
- * @param {PemissionFlagSet} flags
- * The set of permissions which should be used to determine whether the
- * given item and its descendants are expanded.
- */
- var expandReadable = function expandReadable(item, flags) {
-
- // If the current item is expandable and has defined children,
- // determine whether it should be expanded
- if (item.expandable && item.children) {
- angular.forEach(item.children, function expandReadableChild(child) {
-
- // Determine whether the user has READ permission for the
- // current child object
- var readable = false;
- switch (child.type) {
-
- case GroupListItem.Type.CONNECTION:
- readable = flags.connectionPermissions.READ[child.identifier];
- break;
-
- case GroupListItem.Type.CONNECTION_GROUP:
- readable = flags.connectionGroupPermissions.READ[child.identifier];
- break;
-
- case GroupListItem.Type.SHARING_PROFILE:
- readable = flags.sharingProfilePermissions.READ[child.identifier];
- break;
-
- }
-
- // The parent should be expanded by default if the child is
- // expanded by default OR the user has READ permission on the
- // child
- item.expanded |= expandReadable(child, flags) || readable;
-
- });
- }
-
- return item.expanded;
-
- };
-
-
- // Retrieve all connections for which we have ADMINISTER permission
- dataSourceService.apply(
- connectionGroupService.getConnectionGroupTree,
- [selectedDataSource],
- ConnectionGroup.ROOT_IDENTIFIER,
- [PermissionSet.ObjectPermissionType.ADMINISTER]
- )
- .then(function connectionGroupReceived(rootGroups) {
-
- // Convert all received ConnectionGroup objects into GroupListItems
- $scope.rootGroups = {};
- angular.forEach(rootGroups, function addGroupListItem(rootGroup, dataSource) {
- $scope.rootGroups[dataSource] = GroupListItem.fromConnectionGroup(dataSource, rootGroup);
- });
+ }
- }, requestService.WARN);
-
// Query the user's permissions for the current user
dataSourceService.apply(
permissionService.getEffectivePermissions,
@@ -689,48 +566,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.permissions = permissions;
}, requestService.WARN);
- // Update default expanded state whenever connection groups and associated
- // permissions change
- $scope.$watchGroup(['rootGroups', 'permissionFlags'], function updateDefaultExpandedStates() {
- angular.forEach($scope.rootGroups, function updateExpandedStates(rootGroup) {
-
- // Automatically expand all objects with any descendants for which
- // the user has READ permission
- if ($scope.permissionFlags)
- expandReadable(rootGroup, $scope.permissionFlags);
-
- });
- });
-
- /**
- * Available system permission types, as translation string / internal
- * value pairs.
- *
- * @type Object[]
- */
- $scope.systemPermissionTypes = [
- {
- label: "MANAGE_USER.FIELD_HEADER_ADMINISTER_SYSTEM",
- value: PermissionSet.SystemPermissionType.ADMINISTER
- },
- {
- label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_USERS",
- value: PermissionSet.SystemPermissionType.CREATE_USER
- },
- {
- label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_CONNECTIONS",
- value: PermissionSet.SystemPermissionType.CREATE_CONNECTION
- },
- {
- label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_CONNECTION_GROUPS",
- value: PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP
- },
- {
- label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_SHARING_PROFILES",
- value: PermissionSet.SystemPermissionType.CREATE_SHARING_PROFILE
- }
- ];
-
/**
* The set of permissions that will be added to the user when the user is
* saved. Permissions will only be present in this set if they are
@@ -738,7 +573,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
*
* @type PermissionSet
*/
- var permissionsAdded = new PermissionSet();
+ $scope.permissionsAdded = new PermissionSet();
/**
* The set of permissions that will be removed from the user when the user
@@ -747,336 +582,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
*
* @type PermissionSet
*/
- var permissionsRemoved = new PermissionSet();
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the addition of the given system permission.
- *
- * @param {String} type
- * The system permission to add, as defined by
- * PermissionSet.SystemPermissionType.
- */
- var addSystemPermission = function addSystemPermission(type) {
-
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasSystemPermission(permissionsRemoved, type))
- PermissionSet.removeSystemPermission(permissionsRemoved, type);
-
- // Otherwise, explicitly add the permission
- else
- PermissionSet.addSystemPermission(permissionsAdded, type);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the removal of the given system permission.
- *
- * @param {String} type
- * The system permission to remove, as defined by
- * PermissionSet.SystemPermissionType.
- */
- var removeSystemPermission = function removeSystemPermission(type) {
-
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasSystemPermission(permissionsAdded, type))
- PermissionSet.removeSystemPermission(permissionsAdded, type);
-
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addSystemPermission(permissionsRemoved, type);
-
- };
-
- /**
- * Notifies the controller that a change has been made to the given
- * system permission for the user being edited.
- *
- * @param {String} type
- * The system permission that was changed, as defined by
- * PermissionSet.SystemPermissionType.
- */
- $scope.systemPermissionChanged = function systemPermissionChanged(type) {
-
- // Determine current permission setting
- var granted = $scope.permissionFlags.systemPermissions[type];
-
- // Add/remove permission depending on flag state
- if (granted)
- addSystemPermission(type);
- else
- removeSystemPermission(type);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the addition of the given user permission.
- *
- * @param {String} type
- * The user permission to add, as defined by
- * PermissionSet.ObjectPermissionType.
- *
- * @param {String} identifier
- * The identifier of the user affected by the permission being added.
- */
- var addUserPermission = function addUserPermission(type, identifier) {
-
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasUserPermission(permissionsRemoved, type, identifier))
- PermissionSet.removeUserPermission(permissionsRemoved, type, identifier);
-
- // Otherwise, explicitly add the permission
- else
- PermissionSet.addUserPermission(permissionsAdded, type, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the removal of the given user permission.
- *
- * @param {String} type
- * The user permission to remove, as defined by
- * PermissionSet.ObjectPermissionType.
- *
- * @param {String} identifier
- * The identifier of the user affected by the permission being removed.
- */
- var removeUserPermission = function removeUserPermission(type, identifier) {
-
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasUserPermission(permissionsAdded, type, identifier))
- PermissionSet.removeUserPermission(permissionsAdded, type, identifier);
-
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addUserPermission(permissionsRemoved, type, identifier);
-
- };
-
- /**
- * Notifies the controller that a change has been made to the given user
- * permission for the user being edited.
- *
- * @param {String} type
- * The user permission that was changed, as defined by
- * PermissionSet.ObjectPermissionType.
- *
- * @param {String} identifier
- * The identifier of the user affected by the changed permission.
- */
- $scope.userPermissionChanged = function userPermissionChanged(type, identifier) {
-
- // Determine current permission setting
- var granted = $scope.permissionFlags.userPermissions[type][identifier];
-
- // Add/remove permission depending on flag state
- if (granted)
- addUserPermission(type, identifier);
- else
- removeUserPermission(type, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the addition of the given connection permission.
- *
- * @param {String} identifier
- * The identifier of the connection to add READ permission for.
- */
- var addConnectionPermission = function addConnectionPermission(identifier) {
-
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasConnectionPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly add the permission
- else
- PermissionSet.addConnectionPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the removal of the given connection permission.
- *
- * @param {String} identifier
- * The identifier of the connection to remove READ permission for.
- */
- var removeConnectionPermission = function removeConnectionPermission(identifier) {
-
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasConnectionPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addConnectionPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the addition of the given connection group permission.
- *
- * @param {String} identifier
- * The identifier of the connection group to add READ permission for.
- */
- var addConnectionGroupPermission = function addConnectionGroupPermission(identifier) {
-
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasConnectionGroupPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionGroupPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly add the permission
- else
- PermissionSet.addConnectionGroupPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the removal of the given connection permission.
- *
- * @param {String} identifier
- * The identifier of the connection to remove READ permission for.
- */
- var removeConnectionGroupPermission = function removeConnectionGroupPermission(identifier) {
-
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasConnectionGroupPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionGroupPermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addConnectionGroupPermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the addition of the given sharing profile permission.
- *
- * @param {String} identifier
- * The identifier of the sharing profile to add READ permission for.
- */
- var addSharingProfilePermission = function addSharingProfilePermission(identifier) {
-
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasSharingProfilePermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeSharingProfilePermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly add the permission
- else
- PermissionSet.addSharingProfilePermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
- /**
- * Updates the permissionsAdded and permissionsRemoved permission sets to
- * reflect the removal of the given sharing profile permission.
- *
- * @param {String} identifier
- * The identifier of the sharing profile to remove READ permission for.
- */
- var removeSharingProfilePermission = function removeSharingProfilePermission(identifier) {
-
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasSharingProfilePermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeSharingProfilePermission(permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
-
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addSharingProfilePermission(permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
-
- };
-
-
- // Expose permission query and modification functions to group list template
- $scope.groupListContext = {
-
- /**
- * Returns the PermissionFlagSet that contains the current state of
- * granted permissions.
- *
- * @returns {PermissionFlagSet}
- * The PermissionFlagSet describing the current state of granted
- * permissions for the user being edited.
- */
- getPermissionFlags : function getPermissionFlags() {
- return $scope.permissionFlags;
- },
-
- /**
- * Notifies the controller that a change has been made to the given
- * connection permission for the user being edited. This only applies
- * to READ permissions.
- *
- * @param {String} identifier
- * The identifier of the connection affected by the changed
- * permission.
- */
- connectionPermissionChanged : function connectionPermissionChanged(identifier) {
-
- // Determine current permission setting
- var granted = $scope.permissionFlags.connectionPermissions.READ[identifier];
-
- // Add/remove permission depending on flag state
- if (granted)
- addConnectionPermission(identifier);
- else
- removeConnectionPermission(identifier);
-
- },
-
- /**
- * Notifies the controller that a change has been made to the given
- * connection group permission for the user being edited. This only
- * applies to READ permissions.
- *
- * @param {String} identifier
- * The identifier of the connection group affected by the changed
- * permission.
- */
- connectionGroupPermissionChanged : function connectionGroupPermissionChanged(identifier) {
-
- // Determine current permission setting
- var granted = $scope.permissionFlags.connectionGroupPermissions.READ[identifier];
-
- // Add/remove permission depending on flag state
- if (granted)
- addConnectionGroupPermission(identifier);
- else
- removeConnectionGroupPermission(identifier);
-
- },
-
- /**
- * Notifies the controller that a change has been made to the given
- * sharing profile permission for the user being edited. This only
- * applies to READ permissions.
- *
- * @param {String} identifier
- * The identifier of the sharing profile affected by the changed
- * permission.
- */
- sharingProfilePermissionChanged : function sharingProfilePermissionChanged(identifier) {
-
- // Determine current permission setting
- var granted = $scope.permissionFlags.sharingProfilePermissions.READ[identifier];
-
- // Add/remove permission depending on flag state
- if (granted)
- addSharingProfilePermission(identifier);
- else
- removeSharingProfilePermission(identifier);
-
- }
-
- };
+ $scope.permissionsRemoved = new PermissionSet();
/**
* Cancels all pending edits, returning to the management page.
@@ -1090,7 +596,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
* which is prepopulated with the data from the user currently being edited.
*/
$scope.cloneUser = function cloneUser() {
- $location.path('/manage/' + encodeURIComponent(selectedDataSource) + '/users').search('clone', username);
+ $location.path('/manage/' + encodeURIComponent($scope.dataSource) + '/users').search('clone', username);
};
/**
@@ -1113,10 +619,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Save or create the user, depending on whether the user exists
var saveUserPromise;
- if ($scope.userExists(selectedDataSource))
- saveUserPromise = userService.saveUser(selectedDataSource, $scope.user);
+ if ($scope.userExists($scope.dataSource))
+ saveUserPromise = userService.saveUser($scope.dataSource, $scope.user);
else
- saveUserPromise = userService.createUser(selectedDataSource, $scope.user);
+ saveUserPromise = userService.createUser($scope.dataSource, $scope.user);
saveUserPromise.then(function savedUser() {
@@ -1124,21 +630,21 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
if ($scope.selfUsername !== $scope.user.username) {
// Rename added permission
- if (permissionsAdded.userPermissions[$scope.selfUsername]) {
- permissionsAdded.userPermissions[$scope.user.username] = permissionsAdded.userPermissions[$scope.selfUsername];
- delete permissionsAdded.userPermissions[$scope.selfUsername];
+ if ($scope.permissionsAdded.userPermissions[$scope.selfUsername]) {
+ $scope.permissionsAdded.userPermissions[$scope.user.username] = $scope.permissionsAdded.userPermissions[$scope.selfUsername];
+ delete $scope.permissionsAdded.userPermissions[$scope.selfUsername];
}
// Rename removed permission
- if (permissionsRemoved.userPermissions[$scope.selfUsername]) {
- permissionsRemoved.userPermissions[$scope.user.username] = permissionsRemoved.userPermissions[$scope.selfUsername];
- delete permissionsRemoved.userPermissions[$scope.selfUsername];
+ if ($scope.permissionsRemoved.userPermissions[$scope.selfUsername]) {
+ $scope.permissionsRemoved.userPermissions[$scope.user.username] = $scope.permissionsRemoved.userPermissions[$scope.selfUsername];
+ delete $scope.permissionsRemoved.userPermissions[$scope.selfUsername];
}
}
// Upon success, save any changed permissions
- permissionService.patchPermissions(selectedDataSource, $scope.user.username, permissionsAdded, permissionsRemoved)
+ permissionService.patchPermissions($scope.dataSource, $scope.user.username, $scope.permissionsAdded, $scope.permissionsRemoved)
.then(function patchedUserPermissions() {
$location.url('/settings/users');
}, guacNotification.SHOW_REQUEST_ERROR);
@@ -1180,7 +686,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var deleteUserImmediately = function deleteUserImmediately() {
// Delete the user
- userService.deleteUser(selectedDataSource, $scope.user)
+ userService.deleteUser($scope.dataSource, $scope.user)
.then(function deletedUser() {
$location.path('/settings/users');
}, guacNotification.SHOW_REQUEST_ERROR);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
new file mode 100644
index 0000000..c4be071
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
@@ -0,0 +1,406 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A directive for manipulating the connection permissions granted within a
+ * given {@link PermissionFlagSet}, tracking the specific permissions added or
+ * removed within a separate pair of {@link PermissionSet} objects.
+ */
+angular.module('manage').directive('connectionPermissionEditor', ['$injector',
+ function connectionPermissionEditor($injector) {
+
+ // Required types
+ var ConnectionGroup = $injector.get('ConnectionGroup');
+ var GroupListItem = $injector.get('GroupListItem');
+ var PermissionSet = $injector.get('PermissionSet');
+
+ // Required services
+ var connectionGroupService = $injector.get('connectionGroupService');
+ var dataSourceService = $injector.get('dataSourceService');
+ var requestService = $injector.get('requestService');
+
+ var directive = {
+
+ // Element only
+ restrict: 'E',
+ replace: true,
+
+ scope: {
+
+ /**
+ * The unique identifier of the data source associated with the
+ * permissions being manipulated.
+ *
+ * @type String
+ */
+ dataSource : '=',
+
+ /**
+ * The current state of the permissions being manipulated. This
+ * {@link PemissionFlagSet} will be modified as changes are made
+ * through this permission editor.
+ *
+ * @type PermissionFlagSet
+ */
+ permissionFlags : '=',
+
+ /**
+ * The set of permissions that have been added, relative to the
+ * initial state of the permissions being manipulated.
+ *
+ * @type PermissionSet
+ */
+ permissionsAdded : '=',
+
+ /**
+ * The set of permissions that have been added, relative to the
+ * initial state of the permissions being manipulated.
+ *
+ * @type PermissionSet
+ */
+ permissionsRemoved : '='
+
+ },
+
+ templateUrl: 'app/manage/templates/connectionPermissionEditor.html'
+
+ };
+
+ directive.controller = ['$scope', function connectionPermissionEditorController($scope) {
+
+ /**
+ * Array of all connection properties that are filterable.
+ *
+ * @type String[]
+ */
+ $scope.filteredConnectionProperties = [
+ 'name',
+ 'protocol'
+ ];
+
+ /**
+ * Array of all connection group properties that are filterable.
+ *
+ * @type String[]
+ */
+ $scope.filteredConnectionGroupProperties = [
+ 'name'
+ ];
+
+ /**
+ * A map of data source identifiers to the root connection groups within
+ * thost data sources. As only one data source is applicable to any
+ * particular permission set being edited/created, this will only
+ * contain a single key.
+ *
+ * @type Object.<String, GroupListItem>
+ */
+ $scope.rootGroups = null;
+
+ // Retrieve all connections for which we have ADMINISTER permission
+ dataSourceService.apply(
+ connectionGroupService.getConnectionGroupTree,
+ [$scope.dataSource],
+ ConnectionGroup.ROOT_IDENTIFIER,
+ [PermissionSet.ObjectPermissionType.ADMINISTER]
+ )
+ .then(function connectionGroupReceived(rootGroups) {
+
+ // Convert all received ConnectionGroup objects into GroupListItems
+ $scope.rootGroups = {};
+ angular.forEach(rootGroups, function addGroupListItem(rootGroup, dataSource) {
+ $scope.rootGroups[dataSource] = GroupListItem.fromConnectionGroup(dataSource, rootGroup);
+ });
+
+ }, requestService.WARN);
+
+ /**
+ * Expands all items within the tree descending from the given
+ * GroupListItem which have at least one descendant for which explicit
+ * READ permission is granted. The expanded state of all other items is
+ * left untouched.
+ *
+ * @param {GroupListItem} item
+ * The GroupListItem which should be conditionally expanded
+ * depending on whether READ permission is granted for any of its
+ * descendants.
+ *
+ * @param {PemissionFlagSet} flags
+ * The set of permissions which should be used to determine whether
+ * the given item and its descendants are expanded.
+ */
+ var expandReadable = function expandReadable(item, flags) {
+
+ // If the current item is expandable and has defined children,
+ // determine whether it should be expanded
+ if (item.expandable && item.children) {
+ angular.forEach(item.children, function expandReadableChild(child) {
+
+ // Determine whether the permission set contains READ
+ // permission for the current child object
+ var readable = false;
+ switch (child.type) {
+
+ case GroupListItem.Type.CONNECTION:
+ readable = flags.connectionPermissions.READ[child.identifier];
+ break;
+
+ case GroupListItem.Type.CONNECTION_GROUP:
+ readable = flags.connectionGroupPermissions.READ[child.identifier];
+ break;
+
+ case GroupListItem.Type.SHARING_PROFILE:
+ readable = flags.sharingProfilePermissions.READ[child.identifier];
+ break;
+
+ }
+
+ // The parent should be expanded by default if the child is
+ // expanded by default OR the permission set contains READ
+ // permission on the child
+ item.expanded |= expandReadable(child, flags) || readable;
+
+ });
+ }
+
+ return item.expanded;
+
+ };
+
+ // Update default expanded state whenever connection groups and
+ // associated permissions change
+ $scope.$watchGroup(['rootGroups', 'permissionFlags'], function updateDefaultExpandedStates() {
+
+ if (!$scope.rootGroups || !$scope.permissionFlags)
+ return;
+
+ angular.forEach($scope.rootGroups, function updateExpandedStates(rootGroup) {
+
+ // Automatically expand all objects with any descendants for
+ // which the permission set contains READ permission
+ expandReadable(rootGroup, $scope.permissionFlags);
+
+ });
+
+ });
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the addition of the given connection permission.
+ *
+ * @param {String} identifier
+ * The identifier of the connection to add READ permission for.
+ */
+ var addConnectionPermission = function addConnectionPermission(identifier) {
+
+ // If permission was previously removed, simply un-remove it
+ if (PermissionSet.hasConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly add the permission
+ else
+ PermissionSet.addConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the removal of the given connection permission.
+ *
+ * @param {String} identifier
+ * The identifier of the connection to remove READ permission for.
+ */
+ var removeConnectionPermission = function removeConnectionPermission(identifier) {
+
+ // If permission was previously added, simply un-add it
+ if (PermissionSet.hasConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeConnectionPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly remove the permission
+ else
+ PermissionSet.addConnectionPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the addition of the given connection group permission.
+ *
+ * @param {String} identifier
+ * The identifier of the connection group to add READ permission
+ * for.
+ */
+ var addConnectionGroupPermission = function addConnectionGroupPermission(identifier) {
+
+ // If permission was previously removed, simply un-remove it
+ if (PermissionSet.hasConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly add the permission
+ else
+ PermissionSet.addConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the removal of the given connection permission.
+ *
+ * @param {String} identifier
+ * The identifier of the connection to remove READ permission for.
+ */
+ var removeConnectionGroupPermission = function removeConnectionGroupPermission(identifier) {
+
+ // If permission was previously added, simply un-add it
+ if (PermissionSet.hasConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeConnectionGroupPermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly remove the permission
+ else
+ PermissionSet.addConnectionGroupPermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the addition of the given sharing profile permission.
+ *
+ * @param {String} identifier
+ * The identifier of the sharing profile to add READ permission for.
+ */
+ var addSharingProfilePermission = function addSharingProfilePermission(identifier) {
+
+ // If permission was previously removed, simply un-remove it
+ if (PermissionSet.hasSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly add the permission
+ else
+ PermissionSet.addSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the removal of the given sharing profile permission.
+ *
+ * @param {String} identifier
+ * The identifier of the sharing profile to remove READ permission
+ * for.
+ */
+ var removeSharingProfilePermission = function removeSharingProfilePermission(identifier) {
+
+ // If permission was previously added, simply un-add it
+ if (PermissionSet.hasSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier))
+ PermissionSet.removeSharingProfilePermission($scope.permissionsAdded, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ // Otherwise, explicitly remove the permission
+ else
+ PermissionSet.addSharingProfilePermission($scope.permissionsRemoved, PermissionSet.ObjectPermissionType.READ, identifier);
+
+ };
+
+ // Expose permission query and modification functions to group list template
+ $scope.groupListContext = {
+
+ /**
+ * Returns the PermissionFlagSet that contains the current state of
+ * granted permissions.
+ *
+ * @returns {PermissionFlagSet}
+ * The PermissionFlagSet describing the current state of granted
+ * permissions for the permission set being edited.
+ */
+ getPermissionFlags : function getPermissionFlags() {
+ return $scope.permissionFlags;
+ },
+
+ /**
+ * Notifies the controller that a change has been made to the given
+ * connection permission for the permission set being edited. This
+ * only applies to READ permissions.
+ *
+ * @param {String} identifier
+ * The identifier of the connection affected by the changed
+ * permission.
+ */
+ connectionPermissionChanged : function connectionPermissionChanged(identifier) {
+
+ // Determine current permission setting
+ var granted = $scope.permissionFlags.connectionPermissions.READ[identifier];
+
+ // Add/remove permission depending on flag state
+ if (granted)
+ addConnectionPermission(identifier);
+ else
+ removeConnectionPermission(identifier);
+
+ },
+
+ /**
+ * Notifies the controller that a change has been made to the given
+ * connection group permission for the permission set being edited.
+ * This only applies to READ permissions.
+ *
+ * @param {String} identifier
+ * The identifier of the connection group affected by the
+ * changed permission.
+ */
+ connectionGroupPermissionChanged : function connectionGroupPermissionChanged(identifier) {
+
+ // Determine current permission setting
+ var granted = $scope.permissionFlags.connectionGroupPermissions.READ[identifier];
+
+ // Add/remove permission depending on flag state
+ if (granted)
+ addConnectionGroupPermission(identifier);
+ else
+ removeConnectionGroupPermission(identifier);
+
+ },
+
+ /**
+ * Notifies the controller that a change has been made to the given
+ * sharing profile permission for the permission set being edited.
+ * This only applies to READ permissions.
+ *
+ * @param {String} identifier
+ * The identifier of the sharing profile affected by the changed
+ * permission.
+ */
+ sharingProfilePermissionChanged : function sharingProfilePermissionChanged(identifier) {
+
+ // Determine current permission setting
+ var granted = $scope.permissionFlags.sharingProfilePermissions.READ[identifier];
+
+ // Add/remove permission depending on flag state
+ if (granted)
+ addSharingProfilePermission(identifier);
+ else
+ removeSharingProfilePermission(identifier);
+
+ }
+
+ };
+
+ }];
+
+ return directive;
+
+}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/directives/systemPermissionEditor.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/systemPermissionEditor.js b/guacamole/src/main/webapp/app/manage/directives/systemPermissionEditor.js
new file mode 100644
index 0000000..ec41872
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/directives/systemPermissionEditor.js
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A directive for manipulating the system permissions granted within a given
+ * {@link PermissionFlagSet}, tracking the specific permissions added or
+ * removed within a separate pair of {@link PermissionSet} objects. Optionally,
+ * the permission for a particular user to update themselves (change their own
+ * password/attributes) may also be manipulated.
+ */
+angular.module('manage').directive('systemPermissionEditor', ['$injector',
+ function systemPermissionEditor($injector) {
+
+ // Required services
+ var authenticationService = $injector.get('authenticationService');
+ var dataSourceService = $injector.get('dataSourceService');
+ var permissionService = $injector.get('permissionService');
+ var requestService = $injector.get('requestService');
+
+ // Required types
+ var PermissionSet = $injector.get('PermissionSet');
+
+ var directive = {
+
+ // Element only
+ restrict: 'E',
+ replace: true,
+
+ scope: {
+
+ /**
+ * The unique identifier of the data source associated with the
+ * permissions being manipulated.
+ *
+ * @type String
+ */
+ dataSource : '=',
+
+ /**
+ * The username of the user whose self-update permission (whether
+ * the user has permission to update their own user account) should
+ * be additionally controlled by this editor. If no such user
+ * permissions should be controlled, this should be left undefined.
+ *
+ * @type String
+ */
+ username : '=',
+
+ /**
+ * The current state of the permissions being manipulated. This
+ * {@link PemissionFlagSet} will be modified as changes are made
+ * through this permission editor.
+ *
+ * @type PermissionFlagSet
+ */
+ permissionFlags : '=',
+
+ /**
+ * The set of permissions that have been added, relative to the
+ * initial state of the permissions being manipulated.
+ *
+ * @type PermissionSet
+ */
+ permissionsAdded : '=',
+
+ /**
+ * The set of permissions that have been removed, relative to the
+ * initial state of the permissions being manipulated.
+ *
+ * @type PermissionSet
+ */
+ permissionsRemoved : '='
+
+ },
+
+ templateUrl: 'app/manage/templates/systemPermissionEditor.html'
+
+ };
+
+ directive.controller = ['$scope', function systemPermissionEditorController($scope) {
+
+ /**
+ * The identifiers of all data sources currently available to the
+ * authenticated user.
+ *
+ * @type String[]
+ */
+ var dataSources = authenticationService.getAvailableDataSources();
+
+ /**
+ * The username of the current, authenticated user.
+ *
+ * @type String
+ */
+ var currentUsername = authenticationService.getCurrentUsername();
+
+ /**
+ * Available system permission types, as translation string / internal
+ * value pairs.
+ *
+ * @type Object[]
+ */
+ $scope.systemPermissionTypes = [
+ {
+ label: "MANAGE_USER.FIELD_HEADER_ADMINISTER_SYSTEM",
+ value: PermissionSet.SystemPermissionType.ADMINISTER
+ },
+ {
+ label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_USERS",
+ value: PermissionSet.SystemPermissionType.CREATE_USER
+ },
+ {
+ label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_CONNECTIONS",
+ value: PermissionSet.SystemPermissionType.CREATE_CONNECTION
+ },
+ {
+ label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_CONNECTION_GROUPS",
+ value: PermissionSet.SystemPermissionType.CREATE_CONNECTION_GROUP
+ },
+ {
+ label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_SHARING_PROFILES",
+ value: PermissionSet.SystemPermissionType.CREATE_SHARING_PROFILE
+ }
+ ];
+
+ // Query the permissions granted to the currently-authenticated user
+ dataSourceService.apply(
+ permissionService.getEffectivePermissions,
+ dataSources,
+ currentUsername
+ )
+ .then(function permissionsReceived(permissions) {
+ $scope.permissions = permissions;
+ }, requestService.WARN);
+
+ /**
+ * Returns whether the current user has permission to change the system
+ * permissions granted to users.
+ *
+ * @returns {Boolean}
+ * true if the current user can grant or revoke system permissions
+ * to the permission set being edited, false otherwise.
+ */
+ $scope.canChangeSystemPermissions = function canChangeSystemPermissions() {
+
+ // Do not check if permissions are not yet loaded
+ if (!$scope.permissions)
+ return false;
+
+ // Only the administrator can modify system permissions
+ return PermissionSet.hasSystemPermission($scope.permissions[$scope.dataSource],
+ PermissionSet.SystemPermissionType.ADMINISTER);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the addition of the given system permission.
+ *
+ * @param {String} type
+ * The system permission to add, as defined by
+ * PermissionSet.SystemPermissionType.
+ */
+ var addSystemPermission = function addSystemPermission(type) {
+
+ // If permission was previously removed, simply un-remove it
+ if (PermissionSet.hasSystemPermission($scope.permissionsRemoved, type))
+ PermissionSet.removeSystemPermission($scope.permissionsRemoved, type);
+
+ // Otherwise, explicitly add the permission
+ else
+ PermissionSet.addSystemPermission($scope.permissionsAdded, type);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the removal of the given system permission.
+ *
+ * @param {String} type
+ * The system permission to remove, as defined by
+ * PermissionSet.SystemPermissionType.
+ */
+ var removeSystemPermission = function removeSystemPermission(type) {
+
+ // If permission was previously added, simply un-add it
+ if (PermissionSet.hasSystemPermission($scope.permissionsAdded, type))
+ PermissionSet.removeSystemPermission($scope.permissionsAdded, type);
+
+ // Otherwise, explicitly remove the permission
+ else
+ PermissionSet.addSystemPermission($scope.permissionsRemoved, type);
+
+ };
+
+ /**
+ * Notifies the controller that a change has been made to the given
+ * system permission for the permission set being edited.
+ *
+ * @param {String} type
+ * The system permission that was changed, as defined by
+ * PermissionSet.SystemPermissionType.
+ */
+ $scope.systemPermissionChanged = function systemPermissionChanged(type) {
+
+ // Determine current permission setting
+ var granted = $scope.permissionFlags.systemPermissions[type];
+
+ // Add/remove permission depending on flag state
+ if (granted)
+ addSystemPermission(type);
+ else
+ removeSystemPermission(type);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the addition of the given user permission.
+ *
+ * @param {String} type
+ * The user permission to add, as defined by
+ * PermissionSet.ObjectPermissionType.
+ *
+ * @param {String} identifier
+ * The identifier of the user affected by the permission being added.
+ */
+ var addUserPermission = function addUserPermission(type, identifier) {
+
+ // If permission was previously removed, simply un-remove it
+ if (PermissionSet.hasUserPermission($scope.permissionsRemoved, type, identifier))
+ PermissionSet.removeUserPermission($scope.permissionsRemoved, type, identifier);
+
+ // Otherwise, explicitly add the permission
+ else
+ PermissionSet.addUserPermission($scope.permissionsAdded, type, identifier);
+
+ };
+
+ /**
+ * Updates the permissionsAdded and permissionsRemoved permission sets
+ * to reflect the removal of the given user permission.
+ *
+ * @param {String} type
+ * The user permission to remove, as defined by
+ * PermissionSet.ObjectPermissionType.
+ *
+ * @param {String} identifier
+ * The identifier of the user affected by the permission being
+ * removed.
+ */
+ var removeUserPermission = function removeUserPermission(type, identifier) {
+
+ // If permission was previously added, simply un-add it
+ if (PermissionSet.hasUserPermission($scope.permissionsAdded, type, identifier))
+ PermissionSet.removeUserPermission($scope.permissionsAdded, type, identifier);
+
+ // Otherwise, explicitly remove the permission
+ else
+ PermissionSet.addUserPermission($scope.permissionsRemoved, type, identifier);
+
+ };
+
+ /**
+ * Notifies the controller that a change has been made to the given user
+ * permission for the permission set being edited.
+ *
+ * @param {String} type
+ * The user permission that was changed, as defined by
+ * PermissionSet.ObjectPermissionType.
+ *
+ * @param {String} identifier
+ * The identifier of the user affected by the changed permission.
+ */
+ $scope.userPermissionChanged = function userPermissionChanged(type, identifier) {
+
+ // Determine current permission setting
+ var granted = $scope.permissionFlags.userPermissions[type][identifier];
+
+ // Add/remove permission depending on flag state
+ if (granted)
+ addUserPermission(type, identifier);
+ else
+ removeUserPermission(type, identifier);
+
+ };
+
+ }];
+
+ return directive;
+
+}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/templates/connectionPermissionEditor.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/connectionPermissionEditor.html b/guacamole/src/main/webapp/app/manage/templates/connectionPermissionEditor.html
new file mode 100644
index 0000000..61d3804
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/templates/connectionPermissionEditor.html
@@ -0,0 +1,21 @@
+<div class="connection-permissions">
+ <div class="header">
+ <h2>{{'MANAGE_USER.SECTION_HEADER_CONNECTIONS' | translate}}</h2>
+ <guac-group-list-filter connection-groups="rootGroups"
+ filtered-connection-groups="filteredRootGroups"
+ placeholder="'MANAGE_USER.FIELD_PLACEHOLDER_FILTER' | translate"
+ connection-properties="filteredConnectionProperties"
+ connection-group-properties="filteredConnectionGroupProperties"></guac-group-list-filter>
+ </div>
+ <div class="section">
+ <guac-group-list
+ context="groupListContext"
+ connection-groups="filteredRootGroups"
+ templates="{
+ 'connection' : 'app/manage/templates/connectionPermission.html',
+ 'sharing-profile' : 'app/manage/templates/sharingProfilePermission.html',
+ 'connection-group' : 'app/manage/templates/connectionGroupPermission.html'
+ }"
+ page-size="20"></guac-group-list>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/templates/manageUser.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
index 55b6d30..5fed148 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
@@ -46,47 +46,21 @@
</div>
<!-- System permissions section -->
- <div class="system-permissions" ng-show="canChangePermissions()">
- <h2 class="header">{{'MANAGE_USER.SECTION_HEADER_PERMISSIONS' | translate}}</h2>
- <div class="section">
- <table class="properties">
- <tr ng-repeat="systemPermissionType in systemPermissionTypes"
- ng-show="canChangeSystemPermissions()">
- <th>{{systemPermissionType.label | translate}}</th>
- <td><input type="checkbox" ng-model="permissionFlags.systemPermissions[systemPermissionType.value]"
- ng-change="systemPermissionChanged(systemPermissionType.value)"/></td>
- </tr>
- <tr>
- <th>{{'MANAGE_USER.FIELD_HEADER_CHANGE_OWN_PASSWORD' | translate}}</th>
- <td><input type="checkbox" ng-model="permissionFlags.userPermissions.UPDATE[selfUsername]"
- ng-change="userPermissionChanged('UPDATE', selfUsername)"/></td>
- </tr>
- </table>
- </div>
- </div>
+ <system-permission-editor ng-show="canChangePermissions()"
+ username="selfUsername"
+ data-data-source="dataSource"
+ permission-flags="permissionFlags"
+ permissions-added="permissionsAdded"
+ permissions-removed="permissionsRemoved">
+ </system-permission-editor>
<!-- Connection permissions section -->
- <div class="connection-permissions" ng-show="canChangePermissions()">
- <div class="header">
- <h2>{{'MANAGE_USER.SECTION_HEADER_CONNECTIONS' | translate}}</h2>
- <guac-group-list-filter connection-groups="rootGroups"
- filtered-connection-groups="filteredRootGroups"
- placeholder="'MANAGE_USER.FIELD_PLACEHOLDER_FILTER' | translate"
- connection-properties="filteredConnectionProperties"
- connection-group-properties="filteredConnectionGroupProperties"></guac-group-list-filter>
- </div>
- <div class="section">
- <guac-group-list
- context="groupListContext"
- connection-groups="filteredRootGroups"
- templates="{
- 'connection' : 'app/manage/templates/connectionPermission.html',
- 'sharing-profile' : 'app/manage/templates/sharingProfilePermission.html',
- 'connection-group' : 'app/manage/templates/connectionGroupPermission.html'
- }"
- page-size="20"/>
- </div>
- </div>
+ <connection-permission-editor ng-show="canChangePermissions()"
+ data-data-source="dataSource"
+ permission-flags="permissionFlags"
+ permissions-added="permissionsAdded"
+ permissions-removed="permissionsRemoved">
+ </connection-permission-editor>
<!-- Form action buttons -->
<div class="action-buttons">
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/94ad1f9f/guacamole/src/main/webapp/app/manage/templates/systemPermissionEditor.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/systemPermissionEditor.html b/guacamole/src/main/webapp/app/manage/templates/systemPermissionEditor.html
new file mode 100644
index 0000000..47fec66
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/templates/systemPermissionEditor.html
@@ -0,0 +1,18 @@
+<div class="system-permissions">
+ <h2 class="header">{{'MANAGE_USER.SECTION_HEADER_PERMISSIONS' | translate}}</h2>
+ <div class="section">
+ <table class="properties">
+ <tr ng-repeat="systemPermissionType in systemPermissionTypes"
+ ng-show="canChangeSystemPermissions()">
+ <th>{{systemPermissionType.label | translate}}</th>
+ <td><input type="checkbox" ng-model="permissionFlags.systemPermissions[systemPermissionType.value]"
+ ng-change="systemPermissionChanged(systemPermissionType.value)"/></td>
+ </tr>
+ <tr ng-show="username">
+ <th>{{'MANAGE_USER.FIELD_HEADER_CHANGE_OWN_PASSWORD' | translate}}</th>
+ <td><input type="checkbox" ng-model="permissionFlags.userPermissions.UPDATE[username]"
+ ng-change="userPermissionChanged('UPDATE', username)"/></td>
+ </tr>
+ </table>
+ </div>
+</div>
\ No newline at end of file
[11/21] guacamole-client git commit: GUACAMOLE-220: Include the
identifier of the associated object within ManagementPermissions.
Posted by vn...@apache.org.
GUACAMOLE-220: Include the identifier of the associated object within ManagementPermissions.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/1989c11d
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/1989c11d
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/1989c11d
Branch: refs/heads/master
Commit: 1989c11dd98ac76258d44c001bdf6e362be4f871
Parents: 708c255
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 16:39:02 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../main/webapp/app/manage/types/ManagementPermissions.js | 10 ++++++++++
1 file changed, 10 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1989c11d/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js b/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
index f9a78b7..5d02a76 100644
--- a/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
+++ b/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
@@ -38,6 +38,14 @@ angular.module('manage').factory('ManagementPermissions', ['$injector',
var ManagementPermissions = function ManagementPermissions(template) {
/**
+ * The identifier of the associated object, or null if the object does
+ * not yet exist.
+ *
+ * @type String
+ */
+ this.identifier = template.identifier || null;
+
+ /**
* Whether the user can save the associated object. This could be
* updating an existing object, or creating a new object.
*
@@ -129,6 +137,8 @@ angular.module('manage').factory('ManagementPermissions', ['$injector',
return new ManagementPermissions({
+ identifier : identifier,
+
// A user can save (create or update) an object if they are a
// system-level administrator, OR the object does not yet exist and
// the user has explicit permission to create such objects, OR the
[20/21] guacamole-client git commit: GUACAMOLE-220: Correct grammar
of saveObject() documentation ("to save", not "to saves").
Posted by vn...@apache.org.
GUACAMOLE-220: Correct grammar of saveObject() documentation ("to save", not "to saves").
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/b50e7099
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/b50e7099
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/b50e7099
Branch: refs/heads/master
Commit: b50e70998195b796194b7da72f60baf491b5e713
Parents: ae0512c
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:38:01 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:38:01 2018 -0700
----------------------------------------------------------------------
.../src/main/webapp/app/manage/directives/managementButtons.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b50e7099/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/managementButtons.js b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
index a83b82c..f44515a 100644
--- a/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
+++ b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
@@ -167,7 +167,7 @@ angular.module('manage').directive('managementButtons', ['$injector',
};
/**
- * Invokes the provided save function to saves the current object. If
+ * Invokes the provided save function to save the current object. If
* saving is successful, the user is navigated back to the page they
* started from. If saving fails, an error notification is displayed.
*/
[04/21] guacamole-client git commit: GUACAMOLE-220: Migrate user
management screen to new, common management button directive.
Posted by vn...@apache.org.
GUACAMOLE-220: Migrate user management screen to new, common management button directive.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/0414cdd3
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/0414cdd3
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/0414cdd3
Branch: refs/heads/master
Commit: 0414cdd3edc4f5ba11900750ed26782e335de7b2
Parents: e045da1
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 09:53:26 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 17:20:32 2018 -0700
----------------------------------------------------------------------
.../manage/controllers/manageUserController.js | 105 +++++--------------
.../webapp/app/manage/templates/manageUser.html | 13 +--
2 files changed, 32 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/0414cdd3/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 388e717..b1f4f2e 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -24,6 +24,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
function manageUserController($scope, $injector) {
// Required types
+ var Error = $injector.get('Error');
var ManagementPermissions = $injector.get('ManagementPermissions');
var PageDefinition = $injector.get('PageDefinition');
var PermissionFlagSet = $injector.get('PermissionFlagSet');
@@ -36,7 +37,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var $q = $injector.get('$q');
var authenticationService = $injector.get('authenticationService');
var dataSourceService = $injector.get('dataSourceService');
- var guacNotification = $injector.get('guacNotification');
var permissionService = $injector.get('permissionService');
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
@@ -44,18 +44,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var userService = $injector.get('userService');
/**
- * 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);
- }
- };
-
- /**
* The identifiers of all data sources currently available to the
* authenticated user.
*
@@ -409,9 +397,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
}, requestService.WARN);
/**
- * Cancels all pending edits, returning to the management page.
+ * Cancels all pending edits, returning to the main list of users.
*/
- $scope.cancel = function cancel() {
+ $scope.returnToUserList = function returnToUserList() {
$location.url('/settings/users');
};
@@ -424,21 +412,23 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Saves the user, updating the existing user only.
+ * Saves the current user, creating a new user or updating the existing
+ * user depending on context, returning a promise which is resolved if the
+ * save operation succeeds and rejected if the save operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the save operation succeeds and is
+ * rejected with an {@link Error} if the save operation fails.
*/
$scope.saveUser = function saveUser() {
// Verify passwords match
if ($scope.passwordMatch !== $scope.user.password) {
- guacNotification.showStatus({
- 'className' : 'error',
- 'title' : 'MANAGE_USER.DIALOG_HEADER_ERROR',
- 'text' : {
+ return $q.reject(new Error({
+ translatableMessage : {
key : 'MANAGE_USER.ERROR_PASSWORD_MISMATCH'
- },
- 'actions' : [ ACKNOWLEDGE_ACTION ]
- });
- return;
+ }
+ }));
}
// Save or create the user, depending on whether the user exists
@@ -448,7 +438,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
else
saveUserPromise = userService.createUser($scope.dataSource, $scope.user);
- saveUserPromise.then(function savedUser() {
+ return saveUserPromise.then(function savedUser() {
// Move permission flags if username differs from marker
if ($scope.selfUsername !== $scope.user.username) {
@@ -468,70 +458,25 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
}
// Upon success, save any changed permissions
- permissionService.patchPermissions($scope.dataSource, $scope.user.username, $scope.permissionsAdded, $scope.permissionsRemoved)
+ return permissionService.patchPermissions($scope.dataSource, $scope.user.username, $scope.permissionsAdded, $scope.permissionsRemoved)
.then(function patchedUserPermissions() {
$location.url('/settings/users');
- }, guacNotification.SHOW_REQUEST_ERROR);
+ });
- }, guacNotification.SHOW_REQUEST_ERROR);
+ });
};
/**
- * An action to be provided along with the object sent to showStatus which
- * immediately deletes the current user.
- */
- var DELETE_ACTION = {
- name : "MANAGE_USER.ACTION_DELETE",
- className : "danger",
- // Handle action
- callback : function deleteCallback() {
- deleteUserImmediately();
- guacNotification.showStatus(false);
- }
- };
-
- /**
- * 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);
- }
- };
-
- /**
- * Immediately deletes the current user, without prompting the user for
- * confirmation.
- */
- var deleteUserImmediately = function deleteUserImmediately() {
-
- // Delete the user
- userService.deleteUser($scope.dataSource, $scope.user)
- .then(function deletedUser() {
- $location.path('/settings/users');
- }, guacNotification.SHOW_REQUEST_ERROR);
-
- };
-
- /**
- * Deletes the user, prompting the user first to confirm that deletion is
- * desired.
+ * Deletes the current user, returning a promise which is resolved if the
+ * delete operation succeeds and rejected if the delete operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the delete operation succeeds and is
+ * rejected with an {@link Error} if the delete operation fails.
*/
$scope.deleteUser = function deleteUser() {
-
- // Confirm deletion request
- guacNotification.showStatus({
- 'title' : 'MANAGE_USER.DIALOG_HEADER_CONFIRM_DELETE',
- 'text' : {
- key : 'MANAGE_USER.TEXT_CONFIRM_DELETE'
- },
- 'actions' : [ DELETE_ACTION, CANCEL_ACTION]
- });
-
+ return userService.deleteUser($scope.dataSource, $scope.user);
};
}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/0414cdd3/guacamole/src/main/webapp/app/manage/templates/manageUser.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
index 24db74e..02b3ddc 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
@@ -63,12 +63,13 @@
</connection-permission-editor>
<!-- Form action buttons -->
- <div class="action-buttons">
- <button ng-show="managementPermissions.canSaveObject" ng-click="saveUser()">{{'MANAGE_USER.ACTION_SAVE' | translate}}</button>
- <button ng-show="managementPermissions.canCloneObject" ng-click="cloneUser()">{{'MANAGE_USER.ACTION_CLONE' | translate}}</button>
- <button ng-click="cancel()">{{'MANAGE_USER.ACTION_CANCEL' | translate}}</button>
- <button ng-show="managementPermissions.canDeleteObject" ng-click="deleteUser()" class="danger">{{'MANAGE_USER.ACTION_DELETE' | translate}}</button>
- </div>
+ <management-buttons namespace="'MANAGE_USER'"
+ permissions="managementPermissions"
+ save="saveUser()"
+ delete="deleteUser()"
+ clone="cloneUser()"
+ return="returnToUserList()">
+ </management-buttons>
</div>
[07/21] guacamole-client git commit: GUACAMOLE-220: "Management",
not "managment".
Posted by vn...@apache.org.
GUACAMOLE-220: "Management", not "managment".
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/708c255b
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/708c255b
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/708c255b
Branch: refs/heads/master
Commit: 708c255b8373167806a439332d029ae0f07ef4e5
Parents: 82803c9
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 16:29:25 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../webapp/app/manage/controllers/manageConnectionController.js | 2 +-
.../app/manage/controllers/manageConnectionGroupController.js | 2 +-
.../app/manage/controllers/manageSharingProfileController.js | 2 +-
.../src/main/webapp/app/manage/controllers/manageUserController.js | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/708c255b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index ac55f11..6139781 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -111,7 +111,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
$scope.historyEntryWrappers = null;
/**
- * The managment-related actions that the current user may perform on the
+ * The management-related actions that the current user may perform on the
* connection currently being created/modified, or null if the current
* user's permissions have not yet been loaded.
*
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/708c255b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index 842c395..1a4b64e 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -95,7 +95,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
$scope.connectionGroup = null;
/**
- * The managment-related actions that the current user may perform on the
+ * The management-related actions that the current user may perform on the
* connection group currently being created/modified, or null if the current
* user's permissions have not yet been loaded.
*
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/708c255b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 940c305..7385aa1 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -87,7 +87,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
$scope.parameters = null;
/**
- * The managment-related actions that the current user may perform on the
+ * The management-related actions that the current user may perform on the
* sharing profile currently being created/modified, or null if the current
* user's permissions have not yet been loaded.
*
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/708c255b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index b1f4f2e..dcb87e1 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -136,7 +136,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.permissionsRemoved = new PermissionSet();
/**
- * The managment-related actions that the current user may perform on the
+ * The management-related actions that the current user may perform on the
* user currently being created/modified, or null if the current user's
* permissions have not yet been loaded.
*
[08/21] guacamole-client git commit: GUACAMOLE-220: Migrate sharing
profile management screen to common buttons and permission logic.
Posted by vn...@apache.org.
GUACAMOLE-220: Migrate sharing profile management screen to common buttons and permission logic.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/c1f5ad40
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/c1f5ad40
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/c1f5ad40
Branch: refs/heads/master
Commit: c1f5ad407504c42f42158ea38e9da04e3842f3c1
Parents: 7e1dbf7
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 12:24:33 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../manageSharingProfileController.js | 355 ++++++++-----------
.../manage/templates/manageSharingProfile.html | 15 +-
2 files changed, 161 insertions(+), 209 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/c1f5ad40/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 7414e65..a0a683c 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -24,15 +24,16 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
function manageSharingProfileController($scope, $injector) {
// Required types
- var SharingProfile = $injector.get('SharingProfile');
- var PermissionSet = $injector.get('PermissionSet');
+ var ManagementPermissions = $injector.get('ManagementPermissions');
+ var SharingProfile = $injector.get('SharingProfile');
+ var PermissionSet = $injector.get('PermissionSet');
// Required services
var $location = $injector.get('$location');
+ var $q = $injector.get('$q');
var $routeParams = $injector.get('$routeParams');
var authenticationService = $injector.get('authenticationService');
var connectionService = $injector.get('connectionService');
- var guacNotification = $injector.get('guacNotification');
var permissionService = $injector.get('permissionService');
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
@@ -40,18 +41,6 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
var translationStringService = $injector.get('translationStringService');
/**
- * An action to be provided along with the object sent to showStatus which
- * closes the currently-shown status dialog, effectively canceling the
- * operation which was pending user confirmation.
- */
- var CANCEL_ACTION = {
- name : "MANAGE_SHARING_PROFILE.ACTION_CANCEL",
- callback : function cancelCallback() {
- guacNotification.showStatus(false);
- }
- };
-
- /**
* The unique identifier of the data source containing the sharing profile
* being edited.
*
@@ -98,34 +87,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
$scope.parameters = null;
/**
- * Whether the user can save the sharing profile being edited. This could be
- * updating an existing sharing profile, or creating a new sharing profile.
- *
- * @type Boolean
- */
- $scope.canSaveSharingProfile = null;
-
- /**
- * Whether the user can delete the sharing profile being edited.
- *
- * @type Boolean
- */
- $scope.canDeleteSharingProfile = null;
-
- /**
- * Whether the user can clone the sharing profile being edited.
- *
- * @type Boolean
- */
- $scope.canCloneSharingProfile = null;
-
- /**
- * All permissions associated with the current user, or null if the user's
- * permissions have not yet been loaded.
+ * The managment-related actions that the current user may perform on the
+ * sharing profile currently being created/modified, or null if the current
+ * user's permissions have not yet been loaded.
*
- * @type PermissionSet
+ * @type ManagementPermissions
*/
- $scope.permissions = null;
+ $scope.managementPermissions = null;
/**
* All available sharing profile attributes. This is only the set of
@@ -149,146 +117,157 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
&& $scope.sharingProfile !== null
&& $scope.primaryConnection !== null
&& $scope.parameters !== null
- && $scope.permissions !== null
- && $scope.attributes !== null
- && $scope.canSaveSharingProfile !== null
- && $scope.canDeleteSharingProfile !== null
- && $scope.canCloneSharingProfile !== null;
+ && $scope.managementPermissions !== null
+ && $scope.attributes !== null;
};
- // Pull sharing profile attribute schema
- schemaService.getSharingProfileAttributes($scope.selectedDataSource)
- .then(function attributesReceived(attributes) {
- $scope.attributes = attributes;
- }, requestService.WARN);
-
- // Query the user's permissions for the current sharing profile
- permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
- .then(function permissionsReceived(permissions) {
-
- $scope.permissions = permissions;
-
- // The sharing profile can be saved if it is new or if the user has
- // UPDATE permission for that sharing profile (either explicitly or by
- // virtue of being an administrator)
- $scope.canSaveSharingProfile =
- !identifier
- || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier);
-
- // The sharing profile can be saved only if it exists and the user has
- // DELETE permission (either explicitly or by virtue of being an
- // administrator)
- $scope.canDeleteSharingProfile =
- !!identifier && (
- PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier)
- );
-
- // The sharing profile can be cloned only if it exists, the user has
- // UPDATE permission on the sharing profile being cloned (is able to
- // read parameters), and the user can create new sharing profiles
- $scope.canCloneSharingProfile =
- !!identifier && (
- PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) || (
- PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier)
- && PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_SHARING_PROFILE)
- )
- );
-
- }, requestService.WARN);
-
- // Get protocol metadata
- schemaService.getProtocols($scope.selectedDataSource)
- .then(function protocolsReceived(protocols) {
- $scope.protocols = protocols;
- }, requestService.WARN);
-
- // If we are editing an existing sharing profile, pull its data
- if (identifier) {
-
- // Pull data from existing sharing profile
- sharingProfileService.getSharingProfile($scope.selectedDataSource, identifier)
- .then(function sharingProfileRetrieved(sharingProfile) {
- $scope.sharingProfile = sharingProfile;
- }, requestService.WARN);
-
- // Pull sharing profile parameters
- sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, identifier)
- .then(function parametersReceived(parameters) {
- $scope.parameters = parameters;
- }, requestService.WARN);
-
- }
+ /**
+ * Loads the data associated with the sharing profile having the given
+ * identifier, preparing the interface for making modifications to that
+ * existing sharing profile.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the sharing
+ * profile to load.
+ *
+ * @param {String} identifier
+ * The identifier of the sharing profile to load.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * editing the given sharing profile.
+ */
+ var loadExistingSharingProfile = function loadExistingSharingProfile(dataSource, identifier) {
+ return $q.all({
+ sharingProfile : sharingProfileService.getSharingProfile(dataSource, identifier),
+ parameters : sharingProfileService.getSharingProfileParameters(dataSource, identifier)
+ })
+ .then(function sharingProfileDataRetrieved(values) {
+
+ $scope.sharingProfile = values.sharingProfile;
+ $scope.parameters = values.parameters;
+
+ // Load connection object for associated primary connection
+ return connectionService.getConnection(
+ dataSource,
+ values.sharingProfile.primaryConnectionIdentifier
+ )
+ .then(function connectionRetrieved(connection) {
+ $scope.primaryConnection = connection;
+ });
- // If we are cloning an existing sharing profile, pull its data instead
- else if (cloneSourceIdentifier) {
+ });
+ };
- // Pull data from cloned sharing profile
- sharingProfileService.getSharingProfile($scope.selectedDataSource, cloneSourceIdentifier)
- .then(function sharingProfileRetrieved(sharingProfile) {
+ /**
+ * Loads the data associated with the sharing profile having the given
+ * identifier, preparing the interface for cloning that existing
+ * sharing profile.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the sharing
+ * profile to be cloned.
+ *
+ * @param {String} identifier
+ * The identifier of the sharing profile being cloned.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * cloning the given sharing profile.
+ */
+ var loadClonedSharingProfile = function loadClonedSharingProfile(dataSource, identifier) {
+ return $q.all({
+ sharingProfile : sharingProfileService.getSharingProfile(dataSource, identifier),
+ parameters : sharingProfileService.getSharingProfileParameters(dataSource, identifier)
+ })
+ .then(function sharingProfileDataRetrieved(values) {
- // Store data of sharing profile being cloned
- $scope.sharingProfile = sharingProfile;
+ $scope.sharingProfile = values.sharingProfile;
+ $scope.parameters = values.parameters;
// Clear the identifier field because this sharing profile is new
delete $scope.sharingProfile.identifier;
- }, requestService.WARN);
-
- // Pull sharing profile parameters from cloned sharing profile
- sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, cloneSourceIdentifier)
- .then(function parametersReceived(parameters) {
- $scope.parameters = parameters;
- }, requestService.WARN);
+ // Load connection object for associated primary connection
+ return connectionService.getConnection(
+ dataSource,
+ values.sharingProfile.primaryConnectionIdentifier
+ )
+ .then(function connectionRetrieved(connection) {
+ $scope.primaryConnection = connection;
+ });
- }
+ });
+ };
- // If we are creating a new sharing profile, populate skeleton sharing
- // profile data
- else {
+ /**
+ * Loads skeleton sharing profile data, preparing the interface for
+ * creating a new sharing profile.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * creating a new sharing profile.
+ */
+ var loadSkeletonSharingProfile = function loadSkeletonSharingProfile() {
+ // Use skeleton sharing profile object with no associated parameters
$scope.sharingProfile = new SharingProfile({
primaryConnectionIdentifier : $location.search().parent
});
-
$scope.parameters = {};
- }
-
- // Populate primary connection once its identifier is known
- $scope.$watch('sharingProfile.primaryConnectionIdentifier',
- function retrievePrimaryConnection(identifier) {
-
- if (identifier) {
- connectionService.getConnection($scope.selectedDataSource, identifier)
- .then(function connectionRetrieved(connection) {
- $scope.primaryConnection = connection;
- }, requestService.WARN);
- }
+ return $q.resolve();
- });
+ };
/**
- * Returns whether the current user can change/set all sharing profile
- * attributes for the sharing profile being edited, regardless of whether
- * those attributes are already explicitly associated with that sharing
- * profile.
+ * Loads the data requred for performing the management task requested
+ * through the route parameters given at load time, automatically preparing
+ * the interface for editing an existing sharing profile, cloning an
+ * existing sharing profile, or creating an entirely new sharing profile.
*
- * @returns {Boolean}
- * true if the current user can change all attributes for the sharing
- * profile being edited, regardless of whether those attributes are
- * already explicitly associated with that sharing profile, false
- * otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared
+ * for performing the requested management task.
*/
- $scope.canChangeAllAttributes = function canChangeAllAttributes() {
+ var loadRequestedSharingProfile = function loadRequestedSharingProfile() {
+
+ // If we are editing an existing sharing profile, pull its data
+ if (identifier)
+ return loadExistingSharingProfile($scope.selectedDataSource, identifier);
- // All attributes can be set if we are creating the sharing profile
- return !identifier;
+ // If we are cloning an existing sharing profile, pull its data instead
+ if (cloneSourceIdentifier)
+ return loadClonedSharingProfile($scope.selectedDataSource, cloneSourceIdentifier);
+
+ // If we are creating a new sharing profile, populate skeleton sharing
+ // profile data
+ return loadSkeletonSharingProfile();
};
+
+ // Query the user's permissions for the current sharing profile
+ $q.all({
+ sharingProfileData : loadRequestedSharingProfile(),
+ attributes : schemaService.getSharingProfileAttributes($scope.selectedDataSource),
+ protocols : schemaService.getProtocols($scope.selectedDataSource),
+ permissions : permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
+ })
+ .then(function sharingProfileDataRetrieved(values) {
+
+ $scope.attributes = values.attributes;
+ $scope.protocols = values.protocols;
+
+ $scope.managementPermissions = ManagementPermissions.fromPermissionSet(
+ values.permissions,
+ PermissionSet.SystemPermissionType.CREATE_CONNECTION,
+ PermissionSet.hasConnectionPermission,
+ identifier);
+
+ }, requestService.WARN);
+
/**
* Returns the translation string namespace for the protocol having the
* given name. The namespace will be of the form:
@@ -316,9 +295,10 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
};
/**
- * Cancels all pending edits, returning to the management page.
+ * Cancels all pending edits, returning to the main list of connections
+ * within the selected data source.
*/
- $scope.cancel = function cancel() {
+ $scope.returnToConnectionList = function returnToConnectionList() {
$location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
};
@@ -332,64 +312,35 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
};
/**
- * Saves the sharing profile, creating a new sharing profile or updating
- * the existing sharing profile.
+ * Saves the current sharing profile, creating a new sharing profile or
+ * updating the existing sharing profile, returning a promise which is
+ * resolved if the save operation succeeds and rejected if the save
+ * operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the save operation succeeds and is
+ * rejected with an {@link Error} if the save operation fails.
*/
$scope.saveSharingProfile = function saveSharingProfile() {
$scope.sharingProfile.parameters = $scope.parameters;
// Save the sharing profile
- sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
- .then(function savedSharingProfile() {
- $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
+ return sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile);
};
/**
- * An action to be provided along with the object sent to showStatus which
- * immediately deletes the current sharing profile.
- */
- var DELETE_ACTION = {
- name : "MANAGE_SHARING_PROFILE.ACTION_DELETE",
- className : "danger",
- // Handle action
- callback : function deleteCallback() {
- deleteSharingProfileImmediately();
- guacNotification.showStatus(false);
- }
- };
-
- /**
- * Immediately deletes the current sharing profile, without prompting the
- * user for confirmation.
- */
- var deleteSharingProfileImmediately = function deleteSharingProfileImmediately() {
-
- // Delete the sharing profile
- sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
- .then(function deletedSharingProfile() {
- $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
-
- };
-
- /**
- * Deletes the sharing profile, prompting the user first to confirm that
- * deletion is desired.
+ * Deletes the current sharing profile, returning a promise which is
+ * resolved if the delete operation succeeds and rejected if the delete
+ * operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the delete operation succeeds and is
+ * rejected with an {@link Error} if the delete operation fails.
*/
$scope.deleteSharingProfile = function deleteSharingProfile() {
-
- // Confirm deletion request
- guacNotification.showStatus({
- 'title' : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_CONFIRM_DELETE',
- 'text' : {
- 'key' : 'MANAGE_SHARING_PROFILE.TEXT_CONFIRM_DELETE'
- },
- 'actions' : [ DELETE_ACTION, CANCEL_ACTION]
- });
-
+ return sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile);
};
}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/c1f5ad40/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
index d6c7043..ac52fa3 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
@@ -22,7 +22,7 @@
<!-- Sharing profile attributes section -->
<div class="attributes">
<guac-form namespace="'SHARING_PROFILE_ATTRIBUTES'" content="attributes"
- model="sharingProfile.attributes" model-only="!canChangeAllAttributes()"></guac-form>
+ model="sharingProfile.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
</div>
<!-- Sharing profile parameters -->
@@ -34,11 +34,12 @@
</div>
<!-- Form action buttons -->
- <div class="action-buttons">
- <button ng-show="canSaveSharingProfile" ng-click="saveSharingProfile()">{{'MANAGE_SHARING_PROFILE.ACTION_SAVE' | translate}}</button>
- <button ng-show="canCloneSharingProfile" ng-click="cloneSharingProfile()">{{'MANAGE_SHARING_PROFILE.ACTION_CLONE' | translate}}</button>
- <button ng-click="cancel()">{{'MANAGE_SHARING_PROFILE.ACTION_CANCEL' | translate}}</button>
- <button ng-show="canDeleteSharingProfile" ng-click="deleteSharingProfile()" class="danger">{{'MANAGE_SHARING_PROFILE.ACTION_DELETE' | translate}}</button>
- </div>
+ <management-buttons namespace="'MANAGE_SHARING_PROFILE'"
+ permissions="managementPermissions"
+ save="saveSharingProfile()"
+ delete="deleteSharingProfile()"
+ clone="cloneSharingProfile()"
+ return="returnToConnectionList()">
+ </management-buttons>
</div>
[02/21] guacamole-client git commit: GUACAMOLE-220: Define abstract
object for querying the management-related actions a user may take on a
particular object or type of object.
Posted by vn...@apache.org.
GUACAMOLE-220: Define abstract object for querying the management-related actions a user may take on a particular object or type of object.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/507202d1
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/507202d1
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/507202d1
Branch: refs/heads/master
Commit: 507202d1f3c6b5e96e9f2a6d6f341331af9d34c0
Parents: 94ad1f9
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Apr 30 23:24:15 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Apr 30 23:24:15 2018 -0700
----------------------------------------------------------------------
.../app/manage/types/ManagementPermissions.js | 172 +++++++++++++++++++
1 file changed, 172 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/507202d1/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js b/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
new file mode 100644
index 0000000..f9a78b7
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/types/ManagementPermissions.js
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A service for defining the ManagementPermissions class.
+ */
+angular.module('manage').factory('ManagementPermissions', ['$injector',
+ function defineManagementPermissions($injector) {
+
+ // Required types
+ var PermissionSet = $injector.get('PermissionSet');
+
+ /**
+ * Higher-level representation of the management-related permissions
+ * available to the current user on a particular, arbitrary object.
+ *
+ * @constructor
+ * @param {ManagementPermissions|Object} template
+ * An object whose properties should be copied into the new
+ * ManagementPermissions object.
+ */
+ var ManagementPermissions = function ManagementPermissions(template) {
+
+ /**
+ * Whether the user can save the associated object. This could be
+ * updating an existing object, or creating a new object.
+ *
+ * @type Boolean
+ */
+ this.canSaveObject = template.canSaveObject;
+
+ /**
+ * Whether the user can clone the associated object.
+ *
+ * @type Boolean
+ */
+ this.canCloneObject = template.canCloneObject;
+
+ /**
+ * Whether the user can delete the associated object.
+ *
+ * @type Boolean
+ */
+ this.canDeleteObject = template.canDeleteObject;
+
+ /**
+ * Whether the user can change attributes which are currently
+ * associated with the object.
+ *
+ * @type Boolean
+ */
+ this.canChangeAttributes = template.canChangeAttributes;
+
+ /**
+ * Whether the user can change absolutely all attributes associated
+ * with the object, including those which are not already present.
+ *
+ * @type Boolean
+ */
+ this.canChangeAllAttributes = template.canChangeAllAttributes;
+
+ /**
+ * Whether the user can change permissions which are assigned to the
+ * associated object, if the object is capable of being assigned
+ * permissions.
+ *
+ * @type Boolean
+ */
+ this.canChangePermissions = template.canChangePermissions;
+
+ };
+
+ /**
+ * Creates a new {@link ManagementPermissions} which defines the high-level
+ * actions the current user may take for the given object.
+ *
+ * @param {PermissionSet} permissions
+ * The effective permissions granted to the current user within the
+ * data source associated with the object being managed.
+ *
+ * @param {String} createPermission
+ * The system permission required to create objects of the same type as
+ * the object being managed, as defined by
+ * {@link PermissionSet.SystemPermissionTypes}.
+ *
+ * @param {Function} hasObjectPermission
+ * The function to invoke to test whether a {@link PermissionSet}
+ * contains a particular object permission. The parameters accepted
+ * by this function must be identical to those accepted by
+ * {@link PermissionSet.hasUserPermission()},
+ * {@link PermissionSet.hasConnectionPermission()}, etc.
+ *
+ * @param {String} [identifier]
+ * The identifier of the object being managed. If the object does not
+ * yet exist, this parameter should be omitted or set to null.
+ *
+ * @returns {ManagementPermissions}
+ * A new {@link ManagementPermissions} which defines the high-level
+ * actions the current user may take for the given object.
+ */
+ ManagementPermissions.fromPermissionSet = function fromPermissionSet(
+ permissions, createPermission, hasObjectPermission, identifier) {
+
+ var isAdmin = PermissionSet.hasSystemPermission(permissions,
+ PermissionSet.SystemPermissionType.ADMINISTER);
+
+ var canCreate = PermissionSet.hasSystemPermission(permissions, createPermission);
+ var canAdminister = hasObjectPermission(permissions, PermissionSet.ObjectPermissionType.ADMINISTER, identifier);
+ var canUpdate = hasObjectPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier);
+ var canDelete = hasObjectPermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier);
+
+ var exists = !!identifier;
+
+ return new ManagementPermissions({
+
+ // A user can save (create or update) an object if they are a
+ // system-level administrator, OR the object does not yet exist and
+ // the user has explicit permission to create such objects, OR the
+ // object does already exist and the user has explicit UPDATE
+ // permission on the object
+ canSaveObject : isAdmin || (!exists && canCreate) || canUpdate,
+
+ // A user can clone an object only if the object exists, and
+ // only if they are a system-level administrator OR they have
+ // explicit permission to create such objects
+ canCloneObject : exists && (isAdmin || canCreate),
+
+ // A user can delete an object only if the object exists, and
+ // only if they are a system-level administrator OR they have
+ // explicit DELETE permission on the object
+ canDeleteObject : exists && (isAdmin || canDelete),
+
+ // Attributes in general (with or without existing values) can only
+ // be changed if the object is being created, OR the user is a
+ // system-level administrator, OR the user has explicit UPDATE
+ // permission on the object
+ canChangeAttributes : !exists || isAdmin || canUpdate,
+
+ // A user can change the attributes of an object which are not
+ // explicitly defined on that object when the object is being
+ // created
+ canChangeAllAttributes : !exists,
+
+ // A user can change the system permissions related to an object
+ // if they are a system-level admin, OR they are creating the
+ // object, OR they have explicit ADMINISTER permission on the
+ // existing object
+ canChangePermissions : isAdmin || !exists || canAdminister
+
+ });
+
+ };
+
+ return ManagementPermissions;
+
+}]);
[10/21] guacamole-client git commit: GUACAMOLE-220: Move common
protocol namespace/name retrieval to Protocol class.
Posted by vn...@apache.org.
GUACAMOLE-220: Move common protocol namespace/name retrieval to Protocol class.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/82803c91
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/82803c91
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/82803c91
Branch: refs/heads/master
Commit: 82803c914831bd860f1c9c045e0c5177042c6e24
Parents: c1f5ad4
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 12:42:36 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../controllers/manageConnectionController.js | 47 ++---------------
.../manageSharingProfileController.js | 27 ++--------
.../src/main/webapp/app/rest/restModule.js | 3 +-
.../src/main/webapp/app/rest/types/Protocol.js | 54 +++++++++++++++++++-
4 files changed, 62 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/82803c91/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index 7cd08ac..ac55f11 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -29,6 +29,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
var ManagementPermissions = $injector.get('ManagementPermissions');
var PermissionSet = $injector.get('PermissionSet');
+ var Protocol = $injector.get('Protocol');
// Required services
var $location = $injector.get('$location');
@@ -41,7 +42,6 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
var permissionService = $injector.get('permissionService');
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
- var translationStringService = $injector.get('translationStringService');
/**
* The unique identifier of the data source containing the connection being
@@ -295,51 +295,14 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
}, angular.noop);
/**
- * Returns the translation string namespace for the protocol having the
- * given name. The namespace will be of the form:
- *
- * <code>PROTOCOL_NAME</code>
- *
- * where <code>NAME</code> is the protocol name transformed via
- * translationStringService.canonicalize().
- *
- * @param {String} protocolName
- * The name of the protocol.
- *
- * @returns {String}
- * The translation namespace for the protocol specified, or null if no
- * namespace could be generated.
+ * @borrows Protocol.getNamespace
*/
- $scope.getNamespace = function getNamespace(protocolName) {
-
- // Do not generate a namespace if no protocol is selected
- if (!protocolName)
- return null;
-
- return 'PROTOCOL_' + translationStringService.canonicalize(protocolName);
-
- };
+ $scope.getNamespace = Protocol.getNamespace;
/**
- * Given the internal name of a protocol, produces the translation string
- * for the localized version of that protocol's name. The translation
- * string will be of the form:
- *
- * <code>NAMESPACE.NAME<code>
- *
- * where <code>NAMESPACE</code> is the namespace generated from
- * $scope.getNamespace().
- *
- * @param {String} protocolName
- * The name of the protocol.
- *
- * @returns {String}
- * The translation string which produces the localized name of the
- * protocol specified.
+ * @borrows Protocol.getName
*/
- $scope.getProtocolName = function getProtocolName(protocolName) {
- return $scope.getNamespace(protocolName) + '.NAME';
- };
+ $scope.getProtocolName = Protocol.getName;
/**
* Cancels all pending edits, returning to the main list of connections
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/82803c91/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index a0a683c..940c305 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -27,6 +27,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
var ManagementPermissions = $injector.get('ManagementPermissions');
var SharingProfile = $injector.get('SharingProfile');
var PermissionSet = $injector.get('PermissionSet');
+ var Protocol = $injector.get('Protocol');
// Required services
var $location = $injector.get('$location');
@@ -38,7 +39,6 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
var sharingProfileService = $injector.get('sharingProfileService');
- var translationStringService = $injector.get('translationStringService');
/**
* The unique identifier of the data source containing the sharing profile
@@ -269,30 +269,9 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
}, requestService.WARN);
/**
- * Returns the translation string namespace for the protocol having the
- * given name. The namespace will be of the form:
- *
- * <code>PROTOCOL_NAME</code>
- *
- * where <code>NAME</code> is the protocol name transformed via
- * translationStringService.canonicalize().
- *
- * @param {String} protocolName
- * The name of the protocol.
- *
- * @returns {String}
- * The translation namespace for the protocol specified, or null if no
- * namespace could be generated.
+ * @borrows Protocol.getNamespace
*/
- $scope.getNamespace = function getNamespace(protocolName) {
-
- // Do not generate a namespace if no protocol is selected
- if (!protocolName)
- return null;
-
- return 'PROTOCOL_' + translationStringService.canonicalize(protocolName);
-
- };
+ $scope.getNamespace = Protocol.getNamespace;
/**
* Cancels all pending edits, returning to the main list of connections
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/82803c91/guacamole/src/main/webapp/app/rest/restModule.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/restModule.js b/guacamole/src/main/webapp/app/rest/restModule.js
index f409e95..23901c0 100644
--- a/guacamole/src/main/webapp/app/rest/restModule.js
+++ b/guacamole/src/main/webapp/app/rest/restModule.js
@@ -22,5 +22,6 @@
* Guacamole web application.
*/
angular.module('rest', [
- 'auth'
+ 'auth',
+ 'locale'
]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/82803c91/guacamole/src/main/webapp/app/rest/types/Protocol.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/types/Protocol.js b/guacamole/src/main/webapp/app/rest/types/Protocol.js
index cfb26f0..0b86d5b 100644
--- a/guacamole/src/main/webapp/app/rest/types/Protocol.js
+++ b/guacamole/src/main/webapp/app/rest/types/Protocol.js
@@ -20,8 +20,11 @@
/**
* Service which defines the Protocol class.
*/
-angular.module('rest').factory('Protocol', [function defineProtocol() {
-
+angular.module('rest').factory('Protocol', ['$injector', function defineProtocol($injector) {
+
+ // Required services
+ var translationStringService = $injector.get('translationStringService');
+
/**
* The object returned by REST API calls when representing the data
* associated with a supported remote desktop protocol.
@@ -64,6 +67,53 @@ angular.module('rest').factory('Protocol', [function defineProtocol() {
};
+ /**
+ * Returns the translation string namespace for the protocol having the
+ * given name. The namespace will be of the form:
+ *
+ * <code>PROTOCOL_NAME</code>
+ *
+ * where <code>NAME</code> is the protocol name transformed via
+ * translationStringService.canonicalize().
+ *
+ * @param {String} protocolName
+ * The name of the protocol.
+ *
+ * @returns {String}
+ * The translation namespace for the protocol specified, or null if no
+ * namespace could be generated.
+ */
+ Protocol.getNamespace = function getNamespace(protocolName) {
+
+ // Do not generate a namespace if no protocol is selected
+ if (!protocolName)
+ return null;
+
+ return 'PROTOCOL_' + translationStringService.canonicalize(protocolName);
+
+ };
+
+ /**
+ * Given the internal name of a protocol, produces the translation string
+ * for the localized version of that protocol's name. The translation
+ * string will be of the form:
+ *
+ * <code>NAMESPACE.NAME<code>
+ *
+ * where <code>NAMESPACE</code> is the namespace generated from
+ * $scope.getNamespace().
+ *
+ * @param {String} protocolName
+ * The name of the protocol.
+ *
+ * @returns {String}
+ * The translation string which produces the localized name of the
+ * protocol specified.
+ */
+ Protocol.getName = function getProtocolName(protocolName) {
+ return Protocol.getNamespace(protocolName) + '.NAME';
+ };
+
return Protocol;
}]);
\ No newline at end of file
[16/21] guacamole-client git commit: GUACAMOLE-220: Document context
of skeleton user creation.
Posted by vn...@apache.org.
GUACAMOLE-220: Document context of skeleton user creation.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/7ba9c32a
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/7ba9c32a
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/7ba9c32a
Branch: refs/heads/master
Commit: 7ba9c32a0767893860645b9ee22cfe3c1885c355
Parents: f5f516d
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:32:07 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:32:07 2018 -0700
----------------------------------------------------------------------
.../src/main/webapp/app/manage/controllers/manageUserController.js | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/7ba9c32a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 9a90441..1679886 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -305,6 +305,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
if (cloneSourceUsername)
return loadClonedUser($scope.dataSource, cloneSourceUsername);
+ // If we are creating a new user, populate skeleton user data
return loadSkeletonUser();
};
[21/21] guacamole-client git commit: GUACAMOLE-220: Merge extract
common base for management UI.
Posted by vn...@apache.org.
GUACAMOLE-220: Merge extract common base for management UI.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/9b99b180
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/9b99b180
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/9b99b180
Branch: refs/heads/master
Commit: 9b99b18041fe0a7517dc6a82da1bfd401adea525
Parents: 91f19b2 b50e709
Author: Nick Couchman <vn...@apache.org>
Authored: Fri May 4 04:25:59 2018 -0400
Committer: Nick Couchman <vn...@apache.org>
Committed: Fri May 4 04:25:59 2018 -0400
----------------------------------------------------------------------
.../controllers/manageConnectionController.js | 414 +++----
.../manageConnectionGroupController.js | 321 ++---
.../manageSharingProfileController.js | 391 +++---
.../manage/controllers/manageUserController.js | 1127 +++---------------
.../directives/connectionPermissionEditor.js | 407 +++++++
.../app/manage/directives/dataSourceTabs.js | 111 ++
.../app/manage/directives/managementButtons.js | 201 ++++
.../manage/directives/systemPermissionEditor.js | 308 +++++
.../templates/connectionPermissionEditor.html | 21 +
.../app/manage/templates/dataSourceTabs.html | 3 +
.../app/manage/templates/manageConnection.html | 15 +-
.../manage/templates/manageConnectionGroup.html | 14 +-
.../manage/templates/manageSharingProfile.html | 15 +-
.../webapp/app/manage/templates/manageUser.html | 81 +-
.../app/manage/templates/managementButtons.html | 6 +
.../templates/systemPermissionEditor.html | 18 +
.../app/manage/types/ManagementPermissions.js | 182 +++
.../src/main/webapp/app/rest/restModule.js | 3 +-
.../src/main/webapp/app/rest/types/Protocol.js | 54 +-
guacamole/src/main/webapp/translations/en.json | 1 +
20 files changed, 2038 insertions(+), 1655 deletions(-)
----------------------------------------------------------------------
[14/21] guacamole-client git commit: GUACAMOLE-220: "required",
not "requred".
Posted by vn...@apache.org.
GUACAMOLE-220: "required", not "requred".
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/5028d85b
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/5028d85b
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/5028d85b
Branch: refs/heads/master
Commit: 5028d85bb1d5de40d3da70e3a263e8a2d9f35a62
Parents: 244dd19
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 21:09:51 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 21:09:51 2018 -0700
----------------------------------------------------------------------
.../webapp/app/manage/controllers/manageConnectionController.js | 2 +-
.../app/manage/controllers/manageConnectionGroupController.js | 2 +-
.../app/manage/controllers/manageSharingProfileController.js | 2 +-
.../src/main/webapp/app/manage/controllers/manageUserController.js | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5028d85b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index 6139781..b84886f 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -243,7 +243,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
};
/**
- * Loads the data requred for performing the management task requested
+ * Loads the data required for performing the management task requested
* through the route parameters given at load time, automatically preparing
* the interface for editing an existing connection, cloning an existing
* connection, or creating an entirely new connection.
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5028d85b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index 1a4b64e..250ebc1 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -201,7 +201,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
};
/**
- * Loads the data requred for performing the management task requested
+ * Loads the data required for performing the management task requested
* through the route parameters given at load time, automatically preparing
* the interface for editing an existing connection group, cloning an
* existing connection group, or creating an entirely new connection group.
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5028d85b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 7385aa1..8b57182 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -222,7 +222,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
};
/**
- * Loads the data requred for performing the management task requested
+ * Loads the data required for performing the management task requested
* through the route parameters given at load time, automatically preparing
* the interface for editing an existing sharing profile, cloning an
* existing sharing profile, or creating an entirely new sharing profile.
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5028d85b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 800ad00..9a90441 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -286,7 +286,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Loads the data requred for performing the management task requested
+ * Loads the data required for performing the management task requested
* through the route parameters given at load time, automatically preparing
* the interface for editing an existing user, cloning an existing user, or
* creating an entirely new user.
[18/21] guacamole-client git commit: GUACAMOLE-220:
removeConnectionGroupPermission() affects connection group permissions,
not connection permissions.
Posted by vn...@apache.org.
GUACAMOLE-220: removeConnectionGroupPermission() affects connection group permissions, not connection permissions.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/2c41e38e
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/2c41e38e
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/2c41e38e
Branch: refs/heads/master
Commit: 2c41e38e557e4f56183ebafca8ec7d5c8632f329
Parents: e8f0c96
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:34:34 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:34:34 2018 -0700
----------------------------------------------------------------------
.../webapp/app/manage/directives/connectionPermissionEditor.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/2c41e38e/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
index da85c11..43e80c2 100644
--- a/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
+++ b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
@@ -260,10 +260,11 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
/**
* Updates the permissionsAdded and permissionsRemoved permission sets
- * to reflect the removal of the given connection permission.
+ * to reflect the removal of the given connection group permission.
*
* @param {String} identifier
- * The identifier of the connection to remove READ permission for.
+ * The identifier of the connection group to remove READ permission
+ * for.
*/
var removeConnectionGroupPermission = function removeConnectionGroupPermission(identifier) {
[05/21] guacamole-client git commit: GUACAMOLE-220: Add common
directive for displaying the save/clone/cancel/delete buttons shared by all
object management pages.
Posted by vn...@apache.org.
GUACAMOLE-220: Add common directive for displaying the save/clone/cancel/delete buttons shared by all object management pages.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/e045da13
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/e045da13
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/e045da13
Branch: refs/heads/master
Commit: e045da132c729d0567f256708d204d607c053f9f
Parents: 4f43ddc
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 09:46:46 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 17:20:32 2018 -0700
----------------------------------------------------------------------
.../app/manage/directives/managementButtons.js | 201 +++++++++++++++++++
.../app/manage/templates/managementButtons.html | 6 +
2 files changed, 207 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/e045da13/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/managementButtons.js b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
new file mode 100644
index 0000000..4074548
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Directive which displays a set of object management buttons (save, delete,
+ * clone, etc.) representing the actions available to the current user in
+ * context of the object being edited/created.
+ */
+angular.module('manage').directive('managementButtons', ['$injector',
+ function managementButtons($injector) {
+
+ // Required services
+ var guacNotification = $injector.get('guacNotification');
+
+ var directive = {
+
+ restrict : 'E',
+ replace : true,
+ templateUrl : 'app/manage/templates/managementButtons.html',
+
+ scope : {
+
+ /**
+ * The translation namespace associated with all applicable
+ * translation strings. This directive requires at least the
+ * following translation strings within the given namespace:
+ *
+ * - ACTION_CANCEL
+ * - ACTION_CLONE
+ * - ACTION_DELETE
+ * - ACTION_SAVE
+ * - DIALOG_HEADER_CONFIRM_DELETE
+ * - TEXT_CONFIRM_DELETE
+ *
+ * @type String
+ */
+ namespace : '=',
+
+ /**
+ * The permissions which dictate the management actions available
+ * to the current user.
+ *
+ * @type ManagementPermissions
+ */
+ permissions : '=',
+
+ /**
+ * The function to invoke to save the arbitrary object being edited
+ * if the current user has permission to do so. The provided
+ * function MUST return a promise which is resolved if the save
+ * operation succeeds and is rejected with an {@link Error} if the
+ * save operation fails.
+ *
+ * @type Function
+ */
+ save : '&',
+
+ /**
+ * The function to invoke when the current user chooses to clone
+ * the object being edited. The provided function MUST perform the
+ * actions necessary to produce an interface which will clone the
+ * object.
+ *
+ * @type Function
+ */
+ clone : '&',
+
+ /**
+ * The function to invoke to delete the arbitrary object being edited
+ * if the current user has permission to do so. The provided
+ * function MUST return a promise which is resolved if the delete
+ * operation succeeds and is rejected with an {@link Error} if the
+ * delete operation fails.
+ *
+ * @type Function
+ */
+ delete : '&',
+
+ /**
+ * The function to invoke when the current user chooses to cancel
+ * the edit in progress, or when a save/delete operation has
+ * succeeded. The provided function MUST perform the actions
+ * necessary to return the user to a reasonable starting point.
+ *
+ * @type Function
+ */
+ return : '&'
+
+ }
+
+ };
+
+ directive.controller = ['$scope', function managementButtonsController($scope) {
+
+ /**
+ * An action to be provided along with the object sent to showStatus which
+ * immediately deletes the current connection.
+ */
+ var DELETE_ACTION = {
+ name : $scope.namespace + '.ACTION_DELETE',
+ className : 'danger',
+ callback : function deleteCallback() {
+ deleteObjectImmediately();
+ guacNotification.showStatus(false);
+ }
+ };
+
+ /**
+ * An action to be provided along with the object sent to showStatus which
+ * closes the currently-shown status dialog.
+ */
+ var CANCEL_ACTION = {
+ name : $scope.namespace + '.ACTION_CANCEL',
+ callback : function cancelCallback() {
+ guacNotification.showStatus(false);
+ }
+ };
+
+ /**
+ * Invokes the provided return function to navigate the user back to
+ * the page they started from.
+ */
+ var navigateBack = function navigateBack() {
+ $scope['return']($scope.$parent);
+ };
+
+ /**
+ * Invokes the provided delete function, immediately deleting the
+ * current object without prompting the user for confirmation. If
+ * deletion is successful, the user is navigated back to the page they
+ * started from. If the deletion fails, an error notification is
+ * displayed.
+ */
+ var deleteObjectImmediately = function deleteObjectImmediately() {
+ $scope['delete']($scope.$parent).then(navigateBack, guacNotification.SHOW_REQUEST_ERROR);
+ };
+
+ /**
+ * Cancels all pending edits, returning to the page the user started
+ * from.
+ */
+ $scope.cancel = navigateBack;
+
+ /**
+ * Cancels all pending edits, invoking the provided clone function to
+ * open an edit page for a new object which is prepopulated with the
+ * data from the current object.
+ */
+ $scope.cloneObject = function cloneObject () {
+ $scope.clone($scope.$parent);
+ };
+
+ /**
+ * Invokes the provided save function to saves the current object. If
+ * saving is successful, the user is navigated back to the page they
+ * started from. If saving fails, an error notification is displayed.
+ */
+ $scope.saveObject = function saveObject() {
+ $scope.save($scope.$parent).then(navigateBack, guacNotification.SHOW_REQUEST_ERROR);
+ };
+
+ /**
+ * Deletes the current object, prompting the user first to confirm that
+ * deletion is desired. If the user confirms that deletion is desired,
+ * the object is deleted through invoking the provided delete function.
+ * The user is automatically navigated back to the page they started
+ * from or given an error notification depending on whether deletion
+ * succeeds.
+ */
+ $scope.deleteObject = function deleteObject() {
+
+ // Confirm deletion request
+ guacNotification.showStatus({
+ title : $scope.namespace + '.DIALOG_HEADER_CONFIRM_DELETE',
+ text : { key : $scope.namespace + '.TEXT_CONFIRM_DELETE' },
+ actions : [ DELETE_ACTION, CANCEL_ACTION]
+ });
+
+ };
+
+ }];
+
+ return directive;
+
+}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/e045da13/guacamole/src/main/webapp/app/manage/templates/managementButtons.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/managementButtons.html b/guacamole/src/main/webapp/app/manage/templates/managementButtons.html
new file mode 100644
index 0000000..d43209a
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/templates/managementButtons.html
@@ -0,0 +1,6 @@
+<div class="action-buttons">
+ <button ng-show="permissions.canSaveObject" ng-click="saveObject()">{{namespace + '.ACTION_SAVE' | translate}}</button>
+ <button ng-show="permissions.canCloneObject" ng-click="cloneObject()">{{namespace + '.ACTION_CLONE' | translate}}</button>
+ <button ng-click="cancel()">{{namespace + '.ACTION_CANCEL' | translate}}</button>
+ <button ng-show="permissions.canDeleteObject" ng-click="deleteObject()" class="danger">{{namespace + '.ACTION_DELETE' | translate}}</button>
+</div>
[09/21] guacamole-client git commit: GUACAMOLE-220: Migrate
connection group management screen to common buttons and permission logic.
Add required clone option.
Posted by vn...@apache.org.
GUACAMOLE-220: Migrate connection group management screen to common buttons and permission logic. Add required clone option.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/7e1dbf7d
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/7e1dbf7d
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/7e1dbf7d
Branch: refs/heads/master
Commit: 7e1dbf7d11f51f7acd8b3ad39e30695bbda15abd
Parents: 00fee4a
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 11:54:38 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../manageConnectionGroupController.js | 321 ++++++++++---------
.../manage/templates/manageConnectionGroup.html | 14 +-
guacamole/src/main/webapp/translations/en.json | 1 +
3 files changed, 174 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/7e1dbf7d/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index de29aff..842c395 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -24,15 +24,16 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
function manageConnectionGroupController($scope, $injector) {
// Required types
- var ConnectionGroup = $injector.get('ConnectionGroup');
- var PermissionSet = $injector.get('PermissionSet');
+ var ConnectionGroup = $injector.get('ConnectionGroup');
+ var ManagementPermissions = $injector.get('ManagementPermissions');
+ var PermissionSet = $injector.get('PermissionSet');
// Required services
var $location = $injector.get('$location');
+ var $q = $injector.get('$q');
var $routeParams = $injector.get('$routeParams');
var authenticationService = $injector.get('authenticationService');
var connectionGroupService = $injector.get('connectionGroupService');
- var guacNotification = $injector.get('guacNotification');
var permissionService = $injector.get('permissionService');
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
@@ -46,6 +47,15 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
$scope.selectedDataSource = $routeParams.dataSource;
/**
+ * The identifier of the original connection group from which this
+ * connection group is being cloned. Only valid if this is a new
+ * connection group.
+ *
+ * @type String
+ */
+ var cloneSourceIdentifier = $location.search().clone;
+
+ /**
* The identifier of the connection group being edited. If a new connection
* group is being created, this will not be defined.
*
@@ -54,6 +64,23 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
var identifier = $routeParams.id;
/**
+ * Available connection group types, as translation string / internal value
+ * pairs.
+ *
+ * @type Object[]
+ */
+ $scope.types = [
+ {
+ label: "MANAGE_CONNECTION_GROUP.NAME_TYPE_ORGANIZATIONAL",
+ value: ConnectionGroup.Type.ORGANIZATIONAL
+ },
+ {
+ label: "MANAGE_CONNECTION_GROUP.NAME_TYPE_BALANCING",
+ value : ConnectionGroup.Type.BALANCING
+ }
+ ];
+
+ /**
* The root connection group of the connection group hierarchy.
*
* @type ConnectionGroup
@@ -68,26 +95,13 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
$scope.connectionGroup = null;
/**
- * Whether the user has UPDATE permission for the current connection group.
- *
- * @type Boolean
- */
- $scope.hasUpdatePermission = null;
-
- /**
- * Whether the user has DELETE permission for the current connection group.
- *
- * @type Boolean
- */
- $scope.hasDeletePermission = null;
-
- /**
- * All permissions associated with the current user, or null if the user's
- * permissions have not yet been loaded.
+ * The managment-related actions that the current user may perform on the
+ * connection group currently being created/modified, or null if the current
+ * user's permissions have not yet been loaded.
*
- * @type PermissionSet
+ * @type ManagementPermissions
*/
- $scope.permissions = null;
+ $scope.managementPermissions = null;
/**
* All available connection group attributes. This is only the set of
@@ -109,177 +123,172 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
return $scope.rootGroup !== null
&& $scope.connectionGroup !== null
- && $scope.permissions !== null
- && $scope.attributes !== null
- && $scope.canSaveConnectionGroup !== null
- && $scope.canDeleteConnectionGroup !== null;
+ && $scope.managementPermissions !== null
+ && $scope.attributes !== null;
};
-
- // Pull connection group attribute schema
- schemaService.getConnectionGroupAttributes($scope.selectedDataSource)
- .then(function attributesReceived(attributes) {
- $scope.attributes = attributes;
- }, requestService.WARN);
-
- // Query the user's permissions for the current connection group
- permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
- .then(function permissionsReceived(permissions) {
-
- $scope.permissions = permissions;
-
- // Check if the connection group is new or if the user has UPDATE permission
- $scope.canSaveConnectionGroup =
- !identifier
- || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier);
-
- // Check if connection group is not new and the user has DELETE permission
- $scope.canDeleteConnectionGroup =
- !!identifier && (
- PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier)
- );
-
- }, requestService.WARN);
-
-
- // Pull connection group hierarchy
- connectionGroupService.getConnectionGroupTree(
- $scope.selectedDataSource,
- ConnectionGroup.ROOT_IDENTIFIER,
- [PermissionSet.ObjectPermissionType.ADMINISTER]
- )
- .then(function connectionGroupReceived(rootGroup) {
- $scope.rootGroup = rootGroup;
- }, requestService.WARN);
- // If we are editing an existing connection group, pull its data
- if (identifier) {
- connectionGroupService.getConnectionGroup($scope.selectedDataSource, identifier)
+ /**
+ * Loads the data associated with the connection group having the given
+ * identifier, preparing the interface for making modifications to that
+ * existing connection group.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the connection
+ * group to load.
+ *
+ * @param {String} identifier
+ * The identifier of the connection group to load.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * editing the given connection group.
+ */
+ var loadExistingConnectionGroup = function loadExistingConnectionGroup(dataSource, identifier) {
+ return connectionGroupService.getConnectionGroup(
+ dataSource,
+ identifier
+ )
.then(function connectionGroupReceived(connectionGroup) {
$scope.connectionGroup = connectionGroup;
- }, requestService.WARN);
- }
-
- // If we are creating a new connection group, populate skeleton connection group data
- else
- $scope.connectionGroup = new ConnectionGroup({
- parentIdentifier : $location.search().parent
});
+ };
/**
- * Available connection group types, as translation string / internal value
- * pairs.
- *
- * @type Object[]
+ * Loads the data associated with the connection group having the given
+ * identifier, preparing the interface for cloning that existing
+ * connection group.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the connection
+ * group to be cloned.
+ *
+ * @param {String} identifier
+ * The identifier of the connection group being cloned.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * cloning the given connection group.
*/
- $scope.types = [
- {
- label: "MANAGE_CONNECTION_GROUP.NAME_TYPE_ORGANIZATIONAL",
- value: ConnectionGroup.Type.ORGANIZATIONAL
- },
- {
- label: "MANAGE_CONNECTION_GROUP.NAME_TYPE_BALANCING",
- value : ConnectionGroup.Type.BALANCING
- }
- ];
+ var loadClonedConnectionGroup = function loadClonedConnectionGroup(dataSource, identifier) {
+ return connectionGroupService.getConnectionGroup(
+ dataSource,
+ identifier
+ )
+ .then(function connectionGroupReceived(connectionGroup) {
+ $scope.connectionGroup = connectionGroup;
+ delete $scope.connectionGroup.identifier;
+ });
+ };
/**
- * Returns whether the current user can change/set all connection group
- * attributes for the connection group being edited, regardless of whether
- * those attributes are already explicitly associated with that connection
- * group.
+ * Loads skeleton connection group data, preparing the interface for
+ * creating a new connection group.
*
- * @returns {Boolean}
- * true if the current user can change all attributes for the
- * connection group being edited, regardless of whether those
- * attributes are already explicitly associated with that connection
- * group, false otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * creating a new connection group.
*/
- $scope.canChangeAllAttributes = function canChangeAllAttributes() {
+ var loadSkeletonConnectionGroup = function loadSkeletonConnectionGroup() {
- // All attributes can be set if we are creating the connection group
- return !identifier;
+ // Use skeleton connection group object with specified parent
+ $scope.connectionGroup = new ConnectionGroup({
+ parentIdentifier : $location.search().parent
+ });
- };
+ return $q.resolve();
- /**
- * Cancels all pending edits, returning to the management page.
- */
- $scope.cancel = function cancel() {
- $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
};
-
+
/**
- * Saves the connection group, creating a new connection group or updating
- * the existing connection group.
+ * Loads the data requred for performing the management task requested
+ * through the route parameters given at load time, automatically preparing
+ * the interface for editing an existing connection group, cloning an
+ * existing connection group, or creating an entirely new connection group.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared
+ * for performing the requested management task.
*/
- $scope.saveConnectionGroup = function saveConnectionGroup() {
+ var loadRequestedConnectionGroup = function loadRequestedConnectionGroup() {
+
+ // If we are editing an existing connection group, pull its data
+ if (identifier)
+ return loadExistingConnectionGroup($scope.selectedDataSource, identifier);
- // Save the connection
- connectionGroupService.saveConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
- .then(function savedConnectionGroup() {
- $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
+ // If we are cloning an existing connection group, pull its data
+ // instead
+ if (cloneSourceIdentifier)
+ return loadClonedConnectionGroup($scope.selectedDataSource, cloneSourceIdentifier);
+
+ // If we are creating a new connection group, populate skeleton
+ // connection group data
+ return loadSkeletonConnectionGroup();
};
-
+
+ // Query the user's permissions for the current connection group
+ $q.all({
+ connectionGroupData : loadRequestedConnectionGroup(),
+ attributes : schemaService.getConnectionGroupAttributes($scope.selectedDataSource),
+ permissions : permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername()),
+ rootGroup : connectionGroupService.getConnectionGroupTree($scope.selectedDataSource, ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER])
+ })
+ .then(function connectionGroupDataRetrieved(values) {
+
+ $scope.attributes = values.attributes;
+ $scope.rootGroup = values.rootGroup;
+
+ $scope.managementPermissions = ManagementPermissions.fromPermissionSet(
+ values.permissions,
+ PermissionSet.SystemPermissionType.CREATE_CONNECTION,
+ PermissionSet.hasConnectionPermission,
+ identifier);
+
+ }, requestService.WARN);
+
/**
- * An action to be provided along with the object sent to showStatus which
- * immediately deletes the current connection group.
+ * Cancels all pending edits, returning to the main list of connections
+ * within the selected data source.
*/
- var DELETE_ACTION = {
- name : "MANAGE_CONNECTION_GROUP.ACTION_DELETE",
- className : "danger",
- // Handle action
- callback : function deleteCallback() {
- deleteConnectionGroupImmediately();
- guacNotification.showStatus(false);
- }
+ $scope.returnToConnectionList = function returnToConnectionList() {
+ $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
};
/**
- * An action to be provided along with the object sent to showStatus which
- * closes the currently-shown status dialog.
+ * Cancels all pending edits, opening an edit page for a new connection
+ * group which is prepopulated with the data from the connection group
+ * currently being edited.
*/
- var CANCEL_ACTION = {
- name : "MANAGE_CONNECTION_GROUP.ACTION_CANCEL",
- // Handle action
- callback : function cancelCallback() {
- guacNotification.showStatus(false);
- }
+ $scope.cloneConnectionGroup = function cloneConnectionGRoup() {
+ $location.path('/manage/' + encodeURIComponent($scope.selectedDataSource) + '/connectionGroups').search('clone', identifier);
};
/**
- * Immediately deletes the current connection group, without prompting the
- * user for confirmation.
+ * Saves the current connection group, creating a new connection group or
+ * updating the existing connection group, returning a promise which is
+ * resolved if the save operation succeeds and rejected if the save
+ * operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the save operation succeeds and is
+ * rejected with an {@link Error} if the save operation fails.
*/
- var deleteConnectionGroupImmediately = function deleteConnectionGroupImmediately() {
-
- // Delete the connection group
- connectionGroupService.deleteConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
- .then(function deletedConnectionGroup() {
- $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
-
+ $scope.saveConnectionGroup = function saveConnectionGroup() {
+ return connectionGroupService.saveConnectionGroup($scope.selectedDataSource, $scope.connectionGroup);
};
-
+
/**
- * Deletes the connection group, prompting the user first to confirm that
- * deletion is desired.
+ * Deletes the current connection group, returning a promise which is
+ * resolved if the delete operation succeeds and rejected if the delete
+ * operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the delete operation succeeds and is
+ * rejected with an {@link Error} if the delete operation fails.
*/
$scope.deleteConnectionGroup = function deleteConnectionGroup() {
-
- // Confirm deletion request
- guacNotification.showStatus({
- 'title' : 'MANAGE_CONNECTION_GROUP.DIALOG_HEADER_CONFIRM_DELETE',
- 'text' : {
- key : 'MANAGE_CONNECTION_GROUP.TEXT_CONFIRM_DELETE'
- },
- 'actions' : [ DELETE_ACTION, CANCEL_ACTION]
- });
-
+ return connectionGroupService.deleteConnectionGroup($scope.selectedDataSource, $scope.connectionGroup);
};
}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/7e1dbf7d/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
index d4c6613..926dc11 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
@@ -41,14 +41,16 @@
<!-- Connection group attributes section -->
<div class="attributes">
<guac-form namespace="'CONNECTION_GROUP_ATTRIBUTES'" content="attributes"
- model="connectionGroup.attributes" model-only="!canChangeAllAttributes()"></guac-form>
+ model="connectionGroup.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
</div>
<!-- Form action buttons -->
- <div class="action-buttons">
- <button ng-show="canSaveConnectionGroup" ng-click="saveConnectionGroup()">{{'MANAGE_CONNECTION_GROUP.ACTION_SAVE' | translate}}</button>
- <button ng-click="cancel()">{{'MANAGE_CONNECTION_GROUP.ACTION_CANCEL' | translate}}</button>
- <button ng-show="canDeleteConnectionGroup" ng-click="deleteConnectionGroup()" class="danger">{{'MANAGE_CONNECTION_GROUP.ACTION_DELETE' | translate}}</button>
- </div>
+ <management-buttons namespace="'MANAGE_CONNECTION_GROUP'"
+ permissions="managementPermissions"
+ save="saveConnectionGroup()"
+ delete="deleteConnectionGroup()"
+ clone="cloneConnectionGroup()"
+ return="returnToConnectionList()">
+ </management-buttons>
</div>
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/7e1dbf7d/guacamole/src/main/webapp/translations/en.json
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/translations/en.json b/guacamole/src/main/webapp/translations/en.json
index a97406e..ca8acb8 100644
--- a/guacamole/src/main/webapp/translations/en.json
+++ b/guacamole/src/main/webapp/translations/en.json
@@ -234,6 +234,7 @@
"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",
[13/21] guacamole-client git commit: GUACAMOLE-220: Move data source
tabs to separate directive.
Posted by vn...@apache.org.
GUACAMOLE-220: Move data source tabs to separate directive.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/6ca076f7
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/6ca076f7
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/6ca076f7
Branch: refs/heads/master
Commit: 6ca076f7fcc59e4d499fa6b15277907f9a88bf8a
Parents: 1989c11
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 17:18:48 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../manage/controllers/manageUserController.js | 70 +++++-------
.../app/manage/directives/dataSourceTabs.js | 111 +++++++++++++++++++
.../app/manage/templates/dataSourceTabs.html | 3 +
.../webapp/app/manage/templates/manageUser.html | 22 ++--
4 files changed, 152 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6ca076f7/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index dcb87e1..27cb933 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -26,7 +26,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Required types
var Error = $injector.get('Error');
var ManagementPermissions = $injector.get('ManagementPermissions');
- var PageDefinition = $injector.get('PageDefinition');
var PermissionFlagSet = $injector.get('PermissionFlagSet');
var PermissionSet = $injector.get('PermissionSet');
var User = $injector.get('User');
@@ -40,7 +39,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
var permissionService = $injector.get('permissionService');
var requestService = $injector.get('requestService');
var schemaService = $injector.get('schemaService');
- var translationStringService = $injector.get('translationStringService');
var userService = $injector.get('userService');
/**
@@ -136,11 +134,14 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.permissionsRemoved = new PermissionSet();
/**
- * The management-related actions that the current user may perform on the
- * user currently being created/modified, or null if the current user's
- * permissions have not yet been loaded.
+ * For each applicable data source, the management-related actions that the
+ * current user may perform on the user account currently being created
+ * or modified, as a map of data source identifier to the
+ * {@link ManagementPermissions} object describing the actions available
+ * within that data source, or null if the current user's permissions have
+ * not yet been loaded.
*
- * @type ManagementPermissions
+ * @type Object.<String, ManagementPermissions>
*/
$scope.managementPermissions = null;
@@ -154,14 +155,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.attributes = null;
/**
- * The pages associated with each user account having the given username.
- * Each user account will be associated with a particular data source.
- *
- * @type PageDefinition[]
- */
- $scope.accountPages = [];
-
- /**
* Returns whether critical data has completed being loaded.
*
* @returns {Boolean}
@@ -349,54 +342,43 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
})
.then(function dataReceived(values) {
- var managementPermissions = {};
-
$scope.attributes = values.attributes;
- // Generate pages for each applicable data source
- $scope.accountPages = [];
+ $scope.managementPermissions = {};
angular.forEach(dataSources, function addAccountPage(dataSource) {
// Determine whether data source contains this user
var exists = (dataSource in $scope.users);
// Calculate management actions available for this specific account
- managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet(
+ $scope.managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet(
values.permissions[dataSource],
PermissionSet.SystemPermissionType.CREATE_USER,
PermissionSet.hasUserPermission,
exists ? username : null);
- // Account is not relevant if it does not exist and cannot be
- // created
- var readOnly = !managementPermissions[dataSource].canSaveObject;
- if (!exists && readOnly)
- return;
-
- // Only the selected data source is relevant when cloning
- if (cloneSourceUsername && dataSource !== $scope.dataSource)
- return;
-
- // Determine class name based on read-only / linked status
- var className;
- if (readOnly) className = 'read-only';
- else if (exists) className = 'linked';
- else className = 'unlinked';
-
- // Add page entry
- $scope.accountPages.push(new PageDefinition({
- name : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME',
- url : '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username || ''),
- className : className
- }));
-
});
- $scope.managementPermissions = managementPermissions[$scope.dataSource];
-
}, requestService.WARN);
/**
+ * Returns the URL for the page which manages the user account currently
+ * being edited under the given data source. The given data source need not
+ * be the same as the data source currently selected.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source that the URL is being
+ * generated for.
+ *
+ * @returns {String}
+ * The URL for the page which manages the user account currently being
+ * edited under the given data source.
+ */
+ $scope.getUserURL = function getUserURL(dataSource) {
+ return '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username || '');
+ };
+
+ /**
* Cancels all pending edits, returning to the main list of users.
*/
$scope.returnToUserList = function returnToUserList() {
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6ca076f7/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js b/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js
new file mode 100644
index 0000000..cf7068f
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Directive which displays a set of tabs pointing to the same object within
+ * different data sources, such as user accounts which span multiple data
+ * sources.
+ */
+angular.module('manage').directive('dataSourceTabs', ['$injector',
+ function dataSourceTabs($injector) {
+
+ // Required types
+ var PageDefinition = $injector.get('PageDefinition');
+
+ // Required services
+ var translationStringService = $injector.get('translationStringService');
+
+ var directive = {
+
+ restrict : 'E',
+ replace : true,
+ templateUrl : 'app/manage/templates/dataSourceTabs.html',
+
+ scope : {
+
+ /**
+ * The permissions which dictate the management actions available
+ * to the current user.
+ *
+ * @type Object.<String, ManagementPermissions>
+ */
+ permissions : '=',
+
+ /**
+ * A function which returns the URL of the object within a given
+ * data source. The relevant data source will be made available to
+ * the Angular expression defining this function as the
+ * "dataSource" variable. No other values will be made available,
+ * including values from the scope.
+ *
+ * @type Function
+ */
+ url : '&'
+
+ }
+
+ };
+
+ directive.controller = ['$scope', function dataSourceTabsController($scope) {
+
+ /**
+ * The set of pages which each manage the same object within different
+ * data sources.
+ *
+ * @type PageDefinition[]
+ */
+ $scope.pages = null;
+
+ // Keep pages synchronized with permissions
+ $scope.$watch('permissions', function permissionsChanged(permissions) {
+
+ $scope.pages = [];
+ angular.forEach(permissions, function addDataSourcePage(managementPermissions, dataSource) {
+
+ // Determine whether data source contains this object
+ var exists = !!managementPermissions.identifier;
+
+ // Data source is not relevant if the associated object does not
+ // exist and cannot be created
+ var readOnly = !managementPermissions.canSaveObject;
+ if (!exists && readOnly)
+ return;
+
+ // Determine class name based on read-only / linked status
+ var className;
+ if (readOnly) className = 'read-only';
+ else if (exists) className = 'linked';
+ else className = 'unlinked';
+
+ // Add page entry
+ $scope.pages.push(new PageDefinition({
+ name : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME',
+ url : $scope.url({ dataSource : dataSource }),
+ className : className
+ }));
+
+ });
+
+ });
+
+ }];
+
+ return directive;
+
+}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6ca076f7/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html b/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html
new file mode 100644
index 0000000..a8a0843
--- /dev/null
+++ b/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html
@@ -0,0 +1,3 @@
+<div class="page-tabs">
+ <guac-page-list pages="pages"></guac-page-list>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6ca076f7/guacamole/src/main/webapp/app/manage/templates/manageUser.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
index 02b3ddc..6770d31 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
@@ -6,17 +6,18 @@
<h2>{{'MANAGE_USER.SECTION_HEADER_EDIT_USER' | translate}}</h2>
<guac-user-menu></guac-user-menu>
</div>
- <div class="page-tabs">
- <guac-page-list pages="accountPages"></guac-page-list>
- </div>
+ <data-data-source-tabs ng-hide="cloneSourceUsername"
+ permissions="managementPermissions"
+ url="getUserURL(dataSource)">
+ </data-data-source-tabs>
<!-- Warn if user is read-only -->
- <div class="section" ng-hide="managementPermissions.canSaveObject">
+ <div class="section" ng-hide="managementPermissions[dataSource].canSaveObject">
<p class="notice read-only">{{'MANAGE_USER.INFO_READ_ONLY' | translate}}</p>
</div>
<!-- Sections applicable to non-read-only users -->
- <div ng-show="managementPermissions.canSaveObject">
+ <div ng-show="managementPermissions[dataSource].canSaveObject">
<!-- User password section -->
<div class="section">
@@ -40,13 +41,14 @@
</div>
<!-- User attributes section -->
- <div class="attributes" ng-show="managementPermissions.canChangeAttributes">
+ <div class="attributes" ng-show="managementPermissions[dataSource].canChangeAttributes">
<guac-form namespace="'USER_ATTRIBUTES'" content="attributes"
- model="user.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
+ model="user.attributes"
+ model-only="!managementPermissions[dataSource].canChangeAllAttributes"></guac-form>
</div>
<!-- System permissions section -->
- <system-permission-editor ng-show="managementPermissions.canChangePermissions"
+ <system-permission-editor ng-show="managementPermissions[dataSource].canChangePermissions"
username="selfUsername"
data-data-source="dataSource"
permission-flags="permissionFlags"
@@ -55,7 +57,7 @@
</system-permission-editor>
<!-- Connection permissions section -->
- <connection-permission-editor ng-show="managementPermissions.canChangePermissions"
+ <connection-permission-editor ng-show="managementPermissions[dataSource].canChangePermissions"
data-data-source="dataSource"
permission-flags="permissionFlags"
permissions-added="permissionsAdded"
@@ -64,7 +66,7 @@
<!-- Form action buttons -->
<management-buttons namespace="'MANAGE_USER'"
- permissions="managementPermissions"
+ permissions="managementPermissions[dataSource]"
save="saveUser()"
delete="deleteUser()"
clone="cloneUser()"
[12/21] guacamole-client git commit: GUACAMOLE-220: Remove
unnecessary userExists() function.
Posted by vn...@apache.org.
GUACAMOLE-220: Remove unnecessary userExists() function.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/244dd19a
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/244dd19a
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/244dd19a
Branch: refs/heads/master
Commit: 244dd19aa0b5b17f28443465d927b6f0d34b21db
Parents: 6ca076f
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 17:19:40 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700
----------------------------------------------------------------------
.../manage/controllers/manageUserController.js | 27 +-------------------
1 file changed, 1 insertion(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/244dd19a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 27cb933..800ad00 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -171,31 +171,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Returns whether the user being edited already exists within the data
- * source specified.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
- *
- * @returns {Boolean}
- * true if the user being edited already exists, false otherwise.
- */
- $scope.userExists = function userExists(dataSource) {
-
- // Do not check if users are not yet loaded
- if (!$scope.users)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
-
- // Account exists only if it was successfully retrieved
- return (dataSource in $scope.users);
-
- };
-
- /**
* Returns whether the current user can edit the username of the user being
* edited within the given data source.
*
@@ -415,7 +390,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Save or create the user, depending on whether the user exists
var saveUserPromise;
- if ($scope.userExists($scope.dataSource))
+ if ($scope.dataSource in $scope.users)
saveUserPromise = userService.saveUser($scope.dataSource, $scope.user);
else
saveUserPromise = userService.createUser($scope.dataSource, $scope.user);
[15/21] guacamole-client git commit: GUACAMOLE-220: Pull primary
connection for new sharing profiles.
Posted by vn...@apache.org.
GUACAMOLE-220: Pull primary connection for new sharing profiles.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/f5f516d8
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/f5f516d8
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/f5f516d8
Branch: refs/heads/master
Commit: f5f516d82a2ebcee654185acb38f798f71a28c81
Parents: 5028d85
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:16:14 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:16:14 2018 -0700
----------------------------------------------------------------------
.../controllers/manageSharingProfileController.js | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f5f516d8/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 8b57182..61bfbe9 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -205,11 +205,15 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
* Loads skeleton sharing profile data, preparing the interface for
* creating a new sharing profile.
*
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the sharing
+ * profile to be created.
+ *
* @returns {Promise}
* A promise which is resolved when the interface has been prepared for
* creating a new sharing profile.
*/
- var loadSkeletonSharingProfile = function loadSkeletonSharingProfile() {
+ var loadSkeletonSharingProfile = function loadSkeletonSharingProfile(dataSource) {
// Use skeleton sharing profile object with no associated parameters
$scope.sharingProfile = new SharingProfile({
@@ -217,7 +221,14 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
});
$scope.parameters = {};
- return $q.resolve();
+ // Load connection object for associated primary connection
+ return connectionService.getConnection(
+ dataSource,
+ $scope.sharingProfile.primaryConnectionIdentifier
+ )
+ .then(function connectionRetrieved(connection) {
+ $scope.primaryConnection = connection;
+ });
};
@@ -243,7 +254,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
// If we are creating a new sharing profile, populate skeleton sharing
// profile data
- return loadSkeletonSharingProfile();
+ return loadSkeletonSharingProfile($scope.selectedDataSource);
};
[06/21] guacamole-client git commit: GUACAMOLE-220: Migrate
connection management screen to common buttons and permission logic.
Posted by vn...@apache.org.
GUACAMOLE-220: Migrate connection management screen to common buttons and permission logic.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/00fee4ac
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/00fee4ac
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/00fee4ac
Branch: refs/heads/master
Commit: 00fee4ac3af746faea9596b7e69af20d8b02d662
Parents: 0414cdd
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 11:22:31 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:27 2018 -0700
----------------------------------------------------------------------
.../controllers/manageConnectionController.js | 369 ++++++++-----------
.../app/manage/templates/manageConnection.html | 15 +-
2 files changed, 166 insertions(+), 218 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/00fee4ac/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index 2bbd999..7cd08ac 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -24,17 +24,18 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
function manageConnectionController($scope, $injector) {
// Required types
- var Connection = $injector.get('Connection');
- var ConnectionGroup = $injector.get('ConnectionGroup');
- var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
- var PermissionSet = $injector.get('PermissionSet');
+ var Connection = $injector.get('Connection');
+ var ConnectionGroup = $injector.get('ConnectionGroup');
+ var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
+ var ManagementPermissions = $injector.get('ManagementPermissions');
+ var PermissionSet = $injector.get('PermissionSet');
// Required services
var $location = $injector.get('$location');
+ var $q = $injector.get('$q');
var $routeParams = $injector.get('$routeParams');
var $translate = $injector.get('$translate');
var authenticationService = $injector.get('authenticationService');
- var guacNotification = $injector.get('guacNotification');
var connectionService = $injector.get('connectionService');
var connectionGroupService = $injector.get('connectionGroupService');
var permissionService = $injector.get('permissionService');
@@ -108,36 +109,15 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
* @type HistoryEntryWrapper[]
*/
$scope.historyEntryWrappers = null;
-
- /**
- * Whether the user can save the connection being edited. This could be
- * updating an existing connection, or creating a new connection.
- *
- * @type Boolean
- */
- $scope.canSaveConnection = null;
-
- /**
- * Whether the user can delete the connection being edited.
- *
- * @type Boolean
- */
- $scope.canDeleteConnection = null;
-
- /**
- * Whether the user can clone the connection being edited.
- *
- * @type Boolean
- */
- $scope.canCloneConnection = null;
/**
- * All permissions associated with the current user, or null if the user's
- * permissions have not yet been loaded.
+ * The managment-related actions that the current user may perform on the
+ * connection currently being created/modified, or null if the current
+ * user's permissions have not yet been loaded.
*
- * @type PermissionSet
+ * @type ManagementPermissions
*/
- $scope.permissions = null;
+ $scope.managementPermissions = null;
/**
* All available connection attributes. This is only the set of attribute
@@ -157,154 +137,163 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
*/
$scope.isLoaded = function isLoaded() {
- return $scope.protocols !== null
- && $scope.rootGroup !== null
- && $scope.connection !== null
- && $scope.parameters !== null
- && $scope.historyDateFormat !== null
- && $scope.historyEntryWrappers !== null
- && $scope.permissions !== null
- && $scope.attributes !== null
- && $scope.canSaveConnection !== null
- && $scope.canDeleteConnection !== null
- && $scope.canCloneConnection !== null;
+ return $scope.protocols !== null
+ && $scope.rootGroup !== null
+ && $scope.connection !== null
+ && $scope.parameters !== null
+ && $scope.historyDateFormat !== null
+ && $scope.historyEntryWrappers !== null
+ && $scope.managementPermissions !== null
+ && $scope.attributes !== null;
};
- // Pull connection attribute schema
- schemaService.getConnectionAttributes($scope.selectedDataSource)
- .then(function attributesReceived(attributes) {
- $scope.attributes = attributes;
- }, requestService.WARN);
-
- // Pull connection group hierarchy
- connectionGroupService.getConnectionGroupTree(
- $scope.selectedDataSource,
- ConnectionGroup.ROOT_IDENTIFIER,
- [PermissionSet.ObjectPermissionType.ADMINISTER]
- )
- .then(function connectionGroupReceived(rootGroup) {
- $scope.rootGroup = rootGroup;
- }, requestService.WARN);
-
- // Query the user's permissions for the current connection
- permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
- .then(function permissionsReceived(permissions) {
-
- $scope.permissions = permissions;
-
- // Check if the connection is new or if the user has UPDATE permission
- $scope.canSaveConnection =
- !identifier
- || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasConnectionPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier);
-
- // Check if connection is not new and the user has DELETE permission
- $scope.canDeleteConnection =
- !!identifier && (
- PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
- || PermissionSet.hasConnectionPermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier)
- );
-
- // Check if the connection is not new and the user has UPDATE and CREATE_CONNECTION permissions
- $scope.canCloneConnection =
- !!identifier && (
- PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) || (
- PermissionSet.hasConnectionPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier)
- && PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_CONNECTION)
- )
- );
-
- }, requestService.WARN);
-
- // Get protocol metadata
- schemaService.getProtocols($scope.selectedDataSource)
- .then(function protocolsReceived(protocols) {
- $scope.protocols = protocols;
- }, requestService.WARN);
-
- // Get history date format
- $translate('MANAGE_CONNECTION.FORMAT_HISTORY_START').then(function historyDateFormatReceived(historyDateFormat) {
- $scope.historyDateFormat = historyDateFormat;
- }, angular.noop);
-
- // If we are editing an existing connection, pull its data
- if (identifier) {
-
- // Pull data from existing connection
- connectionService.getConnection($scope.selectedDataSource, identifier)
- .then(function connectionRetrieved(connection) {
- $scope.connection = connection;
- }, requestService.WARN);
+ /**
+ * Loads the data associated with the connection having the given
+ * identifier, preparing the interface for making modifications to that
+ * existing connection.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the connection to
+ * load.
+ *
+ * @param {String} identifier
+ * The identifier of the connection to load.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * editing the given connection.
+ */
+ var loadExistingConnection = function loadExistingConnection(dataSource, identifier) {
+ return $q.all({
+ connection : connectionService.getConnection(dataSource, identifier),
+ historyEntries : connectionService.getConnectionHistory(dataSource, identifier),
+ parameters : connectionService.getConnectionParameters(dataSource, identifier)
+ })
+ .then(function connectionDataRetrieved(values) {
- // Pull connection history
- connectionService.getConnectionHistory($scope.selectedDataSource, identifier)
- .then(function historyReceived(historyEntries) {
+ $scope.connection = values.connection;
+ $scope.parameters = values.parameters;
// Wrap all history entries for sake of display
$scope.historyEntryWrappers = [];
- historyEntries.forEach(function wrapHistoryEntry(historyEntry) {
- $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));
+ angular.forEach(values.historyEntries, function wrapHistoryEntry(historyEntry) {
+ $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));
});
- }, requestService.WARN);
+ });
+ };
+
+ /**
+ * Loads the data associated with the connection having the given
+ * identifier, preparing the interface for cloning that existing
+ * connection.
+ *
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the connection
+ * to be cloned.
+ *
+ * @param {String} identifier
+ * The identifier of the connection being cloned.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * cloning the given connection.
+ */
+ var loadClonedConnection = function loadClonedConnection(dataSource, identifier) {
+ return $q.all({
+ connection : connectionService.getConnection(dataSource, identifier),
+ parameters : connectionService.getConnectionParameters(dataSource, identifier)
+ })
+ .then(function connectionDataRetrieved(values) {
- // Pull connection parameters
- connectionService.getConnectionParameters($scope.selectedDataSource, identifier)
- .then(function parametersReceived(parameters) {
- $scope.parameters = parameters;
- }, requestService.WARN);
- }
-
- // If we are cloning an existing connection, pull its data instead
- else if (cloneSourceIdentifier) {
+ $scope.connection = values.connection;
+ $scope.parameters = values.parameters;
- // Pull data from cloned connection
- connectionService.getConnection($scope.selectedDataSource, cloneSourceIdentifier)
- .then(function connectionRetrieved(connection) {
- $scope.connection = connection;
-
// Clear the identifier field because this connection is new
delete $scope.connection.identifier;
- }, requestService.WARN);
- // Do not pull connection history
- $scope.historyEntryWrappers = [];
-
- // Pull connection parameters from cloned connection
- connectionService.getConnectionParameters($scope.selectedDataSource, cloneSourceIdentifier)
- .then(function parametersReceived(parameters) {
- $scope.parameters = parameters;
- }, requestService.WARN);
- }
-
- // If we are creating a new connection, populate skeleton connection data
- else {
+ // Cloned connections have no history
+ $scope.historyEntryWrappers = [];
+
+ });
+ };
+
+ /**
+ * Loads skeleton connection data, preparing the interface for creating a
+ * new connection.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * creating a new connection.
+ */
+ var loadSkeletonConnection = function loadSkeletonConnection() {
+
+ // Use skeleton connection object with no associated permissions,
+ // history, or parameters
$scope.connection = new Connection({
protocol : 'vnc',
parentIdentifier : $location.search().parent
});
$scope.historyEntryWrappers = [];
$scope.parameters = {};
- }
+
+ return $q.resolve();
+
+ };
/**
- * Returns whether the current user can change/set all connection
- * attributes for the connection being edited, regardless of whether those
- * attributes are already explicitly associated with that connection.
+ * Loads the data requred for performing the management task requested
+ * through the route parameters given at load time, automatically preparing
+ * the interface for editing an existing connection, cloning an existing
+ * connection, or creating an entirely new connection.
*
- * @returns {Boolean}
- * true if the current user can change all attributes for the
- * connection being edited, regardless of whether those attributes are
- * already explicitly associated with that connection, false otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared
+ * for performing the requested management task.
*/
- $scope.canChangeAllAttributes = function canChangeAllAttributes() {
+ var loadRequestedConnection = function loadRequestedConnection() {
+
+ // If we are editing an existing connection, pull its data
+ if (identifier)
+ return loadExistingConnection($scope.selectedDataSource, identifier);
- // All attributes can be set if we are creating the connection
- return !identifier;
+ // If we are cloning an existing connection, pull its data instead
+ if (cloneSourceIdentifier)
+ return loadClonedConnection($scope.selectedDataSource, cloneSourceIdentifier);
+
+ // If we are creating a new connection, populate skeleton connection data
+ return loadSkeletonConnection();
};
+ // Populate interface with requested data
+ $q.all({
+ connectionData : loadRequestedConnection(),
+ attributes : schemaService.getConnectionAttributes($scope.selectedDataSource),
+ permissions : permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername()),
+ protocols : schemaService.getProtocols($scope.selectedDataSource),
+ rootGroup : connectionGroupService.getConnectionGroupTree($scope.selectedDataSource, ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER])
+ })
+ .then(function dataRetrieved(values) {
+
+ $scope.attributes = values.attributes;
+ $scope.protocols = values.protocols;
+ $scope.rootGroup = values.rootGroup;
+
+ $scope.managementPermissions = ManagementPermissions.fromPermissionSet(
+ values.permissions,
+ PermissionSet.SystemPermissionType.CREATE_CONNECTION,
+ PermissionSet.hasConnectionPermission,
+ identifier);
+
+ }, requestService.WARN);
+
+ // Get history date format
+ $translate('MANAGE_CONNECTION.FORMAT_HISTORY_START').then(function historyDateFormatReceived(historyDateFormat) {
+ $scope.historyDateFormat = historyDateFormat;
+ }, angular.noop);
+
/**
* Returns the translation string namespace for the protocol having the
* given name. The namespace will be of the form:
@@ -353,9 +342,10 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
};
/**
- * Cancels all pending edits, returning to the management page.
+ * Cancels all pending edits, returning to the main list of connections
+ * within the selected data source.
*/
- $scope.cancel = function cancel() {
+ $scope.returnToConnectionList = function returnToConnectionList() {
$location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
};
@@ -368,76 +358,33 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
};
/**
- * Saves the connection, creating a new connection or updating the existing
- * connection.
+ * Saves the current connection, creating a new connection or updating the
+ * existing connection, returning a promise which is resolved if the save
+ * operation succeeds and rejected if the save operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the save operation succeeds and is
+ * rejected with an {@link Error} if the save operation fails.
*/
$scope.saveConnection = function saveConnection() {
$scope.connection.parameters = $scope.parameters;
// Save the connection
- connectionService.saveConnection($scope.selectedDataSource, $scope.connection)
- .then(function savedConnection() {
- $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
+ return connectionService.saveConnection($scope.selectedDataSource, $scope.connection);
};
-
- /**
- * An action to be provided along with the object sent to showStatus which
- * immediately deletes the current connection.
- */
- var DELETE_ACTION = {
- name : "MANAGE_CONNECTION.ACTION_DELETE",
- className : "danger",
- // Handle action
- callback : function deleteCallback() {
- deleteConnectionImmediately();
- guacNotification.showStatus(false);
- }
- };
-
- /**
- * An action to be provided along with the object sent to showStatus which
- * closes the currently-shown status dialog.
- */
- var CANCEL_ACTION = {
- name : "MANAGE_CONNECTION.ACTION_CANCEL",
- // Handle action
- callback : function cancelCallback() {
- guacNotification.showStatus(false);
- }
- };
/**
- * Immediately deletes the current connection, without prompting the user
- * for confirmation.
- */
- var deleteConnectionImmediately = function deleteConnectionImmediately() {
-
- // Delete the connection
- connectionService.deleteConnection($scope.selectedDataSource, $scope.connection)
- .then(function deletedConnection() {
- $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
- }, guacNotification.SHOW_REQUEST_ERROR);
-
- };
-
- /**
- * Deletes the connection, prompting the user first to confirm that
- * deletion is desired.
+ * Deletes the current connection, returning a promise which is resolved if
+ * the delete operation succeeds and rejected if the delete operation fails.
+ *
+ * @returns {Promise}
+ * A promise which is resolved if the delete operation succeeds and is
+ * rejected with an {@link Error} if the delete operation fails.
*/
$scope.deleteConnection = function deleteConnection() {
-
- // Confirm deletion request
- guacNotification.showStatus({
- 'title' : 'MANAGE_CONNECTION.DIALOG_HEADER_CONFIRM_DELETE',
- 'text' : {
- key : 'MANAGE_CONNECTION.TEXT_CONFIRM_DELETE'
- },
- 'actions' : [ DELETE_ACTION, CANCEL_ACTION]
- });
-
+ return connectionService.deleteConnection($scope.selectedDataSource, $scope.connection);
};
}]);
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/00fee4ac/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
index ed10335..e780513 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
@@ -41,7 +41,7 @@
<!-- Connection attributes section -->
<div class="attributes">
<guac-form namespace="'CONNECTION_ATTRIBUTES'" content="attributes"
- model="connection.attributes" model-only="!canChangeAllAttributes()"></guac-form>
+ model="connection.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
</div>
<!-- Connection parameters -->
@@ -53,12 +53,13 @@
</div>
<!-- Form action buttons -->
- <div class="action-buttons">
- <button ng-show="canSaveConnection" ng-click="saveConnection()">{{'MANAGE_CONNECTION.ACTION_SAVE' | translate}}</button>
- <button ng-show="canCloneConnection" ng-click="cloneConnection()">{{'MANAGE_CONNECTION.ACTION_CLONE' | translate}}</button>
- <button ng-click="cancel()">{{'MANAGE_CONNECTION.ACTION_CANCEL' | translate}}</button>
- <button ng-show="canDeleteConnection" ng-click="deleteConnection()" class="danger">{{'MANAGE_CONNECTION.ACTION_DELETE' | translate}}</button>
- </div>
+ <management-buttons namespace="'MANAGE_CONNECTION'"
+ permissions="managementPermissions"
+ save="saveConnection()"
+ delete="deleteConnection()"
+ clone="cloneConnection()"
+ return="returnToConnectionList()">
+ </management-buttons>
<!-- Connection history -->
<h2 class="header">{{'MANAGE_CONNECTION.SECTION_HEADER_HISTORY' | translate}}</h2>
[19/21] guacamole-client git commit: GUACAMOLE-220: Convert
"namespace" attribute of managementButtons directive to string binding.
Posted by vn...@apache.org.
GUACAMOLE-220: Convert "namespace" attribute of managementButtons directive to string binding.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/ae0512c2
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/ae0512c2
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/ae0512c2
Branch: refs/heads/master
Commit: ae0512c2667b261405016a7d164239de8e96610c
Parents: 2c41e38
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:37:19 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:37:19 2018 -0700
----------------------------------------------------------------------
.../src/main/webapp/app/manage/directives/managementButtons.js | 2 +-
.../src/main/webapp/app/manage/templates/manageConnection.html | 2 +-
.../main/webapp/app/manage/templates/manageConnectionGroup.html | 2 +-
.../src/main/webapp/app/manage/templates/manageSharingProfile.html | 2 +-
guacamole/src/main/webapp/app/manage/templates/manageUser.html | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae0512c2/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/managementButtons.js b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
index 4074548..a83b82c 100644
--- a/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
+++ b/guacamole/src/main/webapp/app/manage/directives/managementButtons.js
@@ -50,7 +50,7 @@ angular.module('manage').directive('managementButtons', ['$injector',
*
* @type String
*/
- namespace : '=',
+ namespace : '@',
/**
* The permissions which dictate the management actions available
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae0512c2/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
index e780513..17a1108 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
@@ -53,7 +53,7 @@
</div>
<!-- Form action buttons -->
- <management-buttons namespace="'MANAGE_CONNECTION'"
+ <management-buttons namespace="MANAGE_CONNECTION"
permissions="managementPermissions"
save="saveConnection()"
delete="deleteConnection()"
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae0512c2/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
index 926dc11..0f12180 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageConnectionGroup.html
@@ -45,7 +45,7 @@
</div>
<!-- Form action buttons -->
- <management-buttons namespace="'MANAGE_CONNECTION_GROUP'"
+ <management-buttons namespace="MANAGE_CONNECTION_GROUP"
permissions="managementPermissions"
save="saveConnectionGroup()"
delete="deleteConnectionGroup()"
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae0512c2/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
index ac52fa3..d242e59 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
@@ -34,7 +34,7 @@
</div>
<!-- Form action buttons -->
- <management-buttons namespace="'MANAGE_SHARING_PROFILE'"
+ <management-buttons namespace="MANAGE_SHARING_PROFILE"
permissions="managementPermissions"
save="saveSharingProfile()"
delete="deleteSharingProfile()"
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae0512c2/guacamole/src/main/webapp/app/manage/templates/manageUser.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
index 6770d31..660554b 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
@@ -65,7 +65,7 @@
</connection-permission-editor>
<!-- Form action buttons -->
- <management-buttons namespace="'MANAGE_USER'"
+ <management-buttons namespace="MANAGE_USER"
permissions="managementPermissions[dataSource]"
save="saveUser()"
delete="deleteUser()"
[17/21] guacamole-client git commit: GUACAMOLE-220: Correct
documentation of permissionsRemoved attribute (the permissions have been
removed, not added).
Posted by vn...@apache.org.
GUACAMOLE-220: Correct documentation of permissionsRemoved attribute (the permissions have been removed, not added).
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/e8f0c967
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/e8f0c967
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/e8f0c967
Branch: refs/heads/master
Commit: e8f0c967585d9d576e1c07dbd6528ce6a8ce4beb
Parents: 7ba9c32
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 3 23:33:41 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 3 23:33:41 2018 -0700
----------------------------------------------------------------------
.../webapp/app/manage/directives/connectionPermissionEditor.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/e8f0c967/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
index c4be071..da85c11 100644
--- a/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
+++ b/guacamole/src/main/webapp/app/manage/directives/connectionPermissionEditor.js
@@ -69,7 +69,7 @@ angular.module('manage').directive('connectionPermissionEditor', ['$injector',
permissionsAdded : '=',
/**
- * The set of permissions that have been added, relative to the
+ * The set of permissions that have been removed, relative to the
* initial state of the permissions being manipulated.
*
* @type PermissionSet
[03/21] guacamole-client git commit: GUACAMOLE-220: Migrate user
management controller to ManagementPermissions.
Posted by vn...@apache.org.
GUACAMOLE-220: Migrate user management controller to ManagementPermissions.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/4f43ddc4
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/4f43ddc4
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/4f43ddc4
Branch: refs/heads/master
Commit: 4f43ddc4203a59c7aea6834cfd8b5961c74ba57e
Parents: 507202d
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 00:03:52 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 00:12:58 2018 -0700
----------------------------------------------------------------------
.../manage/controllers/manageUserController.js | 464 ++++++-------------
.../webapp/app/manage/templates/manageUser.html | 18 +-
2 files changed, 153 insertions(+), 329 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/4f43ddc4/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index c385065..388e717 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -24,14 +24,16 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
function manageUserController($scope, $injector) {
// Required types
- var PageDefinition = $injector.get('PageDefinition');
- var PermissionFlagSet = $injector.get('PermissionFlagSet');
- var PermissionSet = $injector.get('PermissionSet');
- var User = $injector.get('User');
+ var ManagementPermissions = $injector.get('ManagementPermissions');
+ var PageDefinition = $injector.get('PageDefinition');
+ var PermissionFlagSet = $injector.get('PermissionFlagSet');
+ var PermissionSet = $injector.get('PermissionSet');
+ var User = $injector.get('User');
// Required services
var $location = $injector.get('$location');
var $routeParams = $injector.get('$routeParams');
+ var $q = $injector.get('$q');
var authenticationService = $injector.get('authenticationService');
var dataSourceService = $injector.get('dataSourceService');
var guacNotification = $injector.get('guacNotification');
@@ -128,13 +130,31 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
$scope.permissionFlags = null;
/**
- * A map of data source identifiers to the set of all permissions
- * associated with the current user under that data source, or null if the
- * user's permissions have not yet been loaded.
+ * The set of permissions that will be added to the user when the user is
+ * saved. Permissions will only be present in this set if they are
+ * manually added, and not later manually removed before saving.
*
- * @type Object.<String, PermissionSet>
+ * @type PermissionSet
*/
- $scope.permissions = null;
+ $scope.permissionsAdded = new PermissionSet();
+
+ /**
+ * The set of permissions that will be removed from the user when the user
+ * is saved. Permissions will only be present in this set if they are
+ * manually removed, and not later manually added before saving.
+ *
+ * @type PermissionSet
+ */
+ $scope.permissionsRemoved = new PermissionSet();
+
+ /**
+ * The managment-related actions that the current user may perform on the
+ * user currently being created/modified, or null if the current user's
+ * permissions have not yet been loaded.
+ *
+ * @type ManagementPermissions
+ */
+ $scope.managementPermissions = null;
/**
* All available user attributes. This is only the set of attribute
@@ -162,11 +182,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
*/
$scope.isLoaded = function isLoaded() {
- return $scope.users !== null
- && $scope.permissionFlags !== null
- && $scope.rootGroups !== null
- && $scope.permissions !== null
- && $scope.attributes !== null;
+ return $scope.users !== null
+ && $scope.permissionFlags !== null
+ && $scope.managementPermissions !== null
+ && $scope.attributes !== null;
};
@@ -196,97 +215,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Returns whether the current user can change attributes explicitly
- * associated with the user being edited within the given data source.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
- *
- * @returns {Boolean}
- * true if the current user can change attributes associated with the
- * user being edited, false otherwise.
- */
- $scope.canChangeAttributes = function canChangeAttributes(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
-
- // Attributes can always be set if we are creating the user
- if (!$scope.userExists(dataSource))
- return true;
-
- // The administrator can always change attributes
- if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
-
- // Otherwise, can change attributes if we have permission to update this user
- return PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.UPDATE, username);
-
- };
-
- /**
- * Returns whether the current user can change/set all user attributes for
- * the user being edited, regardless of whether those attributes are
- * already explicitly associated with that user.
- *
- * @returns {Boolean}
- * true if the current user can change all attributes for the user
- * being edited, regardless of whether those attributes are already
- * explicitly associated with that user, false otherwise.
- */
- $scope.canChangeAllAttributes = function canChangeAllAttributes() {
-
- // All attributes can be set if we are creating the user
- return !$scope.userExists($scope.dataSource);
-
- };
-
- /**
- * Returns whether the current user can change permissions of any kind
- * which are associated with the user being edited within the given data
- * source.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
- *
- * @returns {Boolean}
- * true if the current user can grant or revoke permissions of any kind
- * which are associated with the user being edited, false otherwise.
- */
- $scope.canChangePermissions = function canChangePermissions(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
-
- // Permissions can always be set if we are creating the user
- if (!$scope.userExists(dataSource))
- return true;
-
- // The administrator can always modify permissions
- if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
-
- // Otherwise, can only modify permissions if we have explicit
- // ADMINISTER permission
- return PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.ADMINISTER, username);
-
- };
-
- /**
* Returns whether the current user can edit the username of the user being
* edited within the given data source.
*
@@ -303,151 +231,158 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
};
/**
- * Returns whether the current user can save the user being edited within
- * the given data source. Saving will create or update that user depending
- * on whether the user already exists.
+ * Loads the data associated with the user having the given username,
+ * preparing the interface for making modifications to that existing user.
*
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the user to
+ * load.
*
- * @returns {Boolean}
- * true if the current user can save changes to the user being edited,
- * false otherwise.
- */
- $scope.canSaveUser = function canSaveUser(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
+ * @param {String} username
+ * The username of the user to load.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * editing the given user.
+ */
+ var loadExistingUser = function loadExistingUser(dataSource, username) {
+ return $q.all({
+ users : dataSourceService.apply(userService.getUser, dataSources, username),
+ permissions : permissionService.getPermissions(dataSource, username)
+ })
+ .then(function userDataRetrieved(values) {
- // The administrator can always save users
- if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
+ $scope.users = values.users;
+ $scope.user = values.users[dataSource];
- // If user does not exist, can only save if we have permission to create users
- if (!$scope.userExists(dataSource))
- return PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.CREATE_USER);
+ // Create skeleton user if user does not exist
+ if (!$scope.user)
+ $scope.user = new User({
+ 'username' : username
+ });
- // Otherwise, can only save if we have permission to update this user
- return PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.UPDATE, username);
+ // The current user will be associated with username of the existing
+ // user in the retrieved permission set
+ $scope.selfUsername = username;
+ $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(values.permissions);
+ });
};
/**
- * Returns whether the current user can clone the user being edited within
- * the given data source.
+ * Loads the data associated with the user having the given username,
+ * preparing the interface for cloning that existing user.
*
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
+ * @param {String} dataSource
+ * The unique identifier of the data source containing the user to
+ * be cloned.
*
- * @returns {Boolean}
- * true if the current user can clone the user being edited, false
- * otherwise.
- */
- $scope.canCloneUser = function canCloneUser(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
-
- // If we are not editing an existing user, we cannot clone
- if (!$scope.userExists($scope.dataSource))
- return false;
+ * @param {String} username
+ * The username of the user being cloned.
+ *
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * cloning the given user.
+ */
+ var loadClonedUser = function loadClonedUser(dataSource, username) {
+ return $q.all({
+ users : dataSourceService.apply(userService.getUser, [dataSource], username),
+ permissions : permissionService.getPermissions(dataSource, username)
+ })
+ .then(function userDataRetrieved(values) {
- // The administrator can always clone users
- if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
+ $scope.users = {};
+ $scope.user = values.users[dataSource];
- // Otherwise we need explicit CREATE_USER permission
- return PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.CREATE_USER);
+ // The current user will be associated with cloneSourceUsername in the
+ // retrieved permission set
+ $scope.selfUsername = username;
+ $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(values.permissions);
+ $scope.permissionsAdded = values.permissions;
+ });
};
/**
- * Returns whether the current user can delete the user being edited from
- * the given data source.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
+ * Loads skeleton user data, preparing the interface for creating a new
+ * user.
*
- * @returns {Boolean}
- * true if the current user can delete the user being edited, false
- * otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared for
+ * creating a new user.
*/
- $scope.canDeleteUser = function canDeleteUser(dataSource) {
-
- // Do not check if permissions are not yet loaded
- if (!$scope.permissions)
- return false;
+ var loadSkeletonUser = function loadSkeletonUser() {
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
+ // No users exist regardless of data source if there is no username
+ $scope.users = {};
- // Can't delete what doesn't exist
- if (!$scope.userExists(dataSource))
- return false;
+ // Use skeleton user object with no associated permissions
+ $scope.user = new User();
+ $scope.permissionFlags = new PermissionFlagSet();
- // The administrator can always delete users
- if (PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
+ // As no permissions are yet associated with the user, it is safe to
+ // use any non-empty username as a placeholder for self-referential
+ // permissions
+ $scope.selfUsername = 'SELF';
- // Otherwise, require explicit DELETE permission on the user
- return PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.DELETE, username);
+ return $q.resolve();
};
/**
- * Returns whether the user being edited within the given data source is
- * read-only, and thus cannot be modified by the current user.
- *
- * @param {String} [dataSource]
- * The identifier of the data source to check. If omitted, this will
- * default to the currently-selected data source.
+ * Loads the data requred for performing the management task requested
+ * through the route parameters given at load time, automatically preparing
+ * the interface for editing an existing user, cloning an existing user, or
+ * creating an entirely new user.
*
- * @returns {Boolean}
- * true if the user being edited is actually read-only and cannot be
- * edited at all, false otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared
+ * for performing the requested management task.
*/
- $scope.isReadOnly = function isReadOnly(dataSource) {
+ var loadRequestedUser = function loadRequestedUser() {
- // Use currently-selected data source if unspecified
- dataSource = dataSource || $scope.dataSource;
+ // Pull user data and permissions if we are editing an existing user
+ if (username)
+ return loadExistingUser($scope.dataSource, username);
+
+ // If we are cloning an existing user, pull his/her data instead
+ if (cloneSourceUsername)
+ return loadClonedUser($scope.dataSource, cloneSourceUsername);
- // User is read-only if they cannot be saved
- return !$scope.canSaveUser(dataSource);
+ return loadSkeletonUser();
};
- // Update visible account pages whenever available users/permissions changes
- $scope.$watchGroup(['users', 'permissions'], function updateAccountPages() {
+ // Populate interface with requested data
+ $q.all({
+ userData : loadRequestedUser(),
+ permissions : dataSourceService.apply(permissionService.getEffectivePermissions, dataSources, currentUsername),
+ attributes : schemaService.getUserAttributes($scope.dataSource)
+ })
+ .then(function dataReceived(values) {
+
+ var managementPermissions = {};
+
+ $scope.attributes = values.attributes;
// Generate pages for each applicable data source
$scope.accountPages = [];
angular.forEach(dataSources, function addAccountPage(dataSource) {
// Determine whether data source contains this user
- var linked = $scope.userExists(dataSource);
- var readOnly = $scope.isReadOnly(dataSource);
+ var exists = (dataSource in $scope.users);
+
+ // Calculate management actions available for this specific account
+ managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet(
+ values.permissions[dataSource],
+ PermissionSet.SystemPermissionType.CREATE_USER,
+ PermissionSet.hasUserPermission,
+ exists ? username : null);
// Account is not relevant if it does not exist and cannot be
// created
- if (!linked && readOnly)
+ var readOnly = !managementPermissions[dataSource].canSaveObject;
+ if (!exists && readOnly)
return;
// Only the selected data source is relevant when cloning
@@ -457,7 +392,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
// Determine class name based on read-only / linked status
var className;
if (readOnly) className = 'read-only';
- else if (linked) className = 'linked';
+ else if (exists) className = 'linked';
else className = 'unlinked';
// Add page entry
@@ -469,121 +404,10 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
});
- });
+ $scope.managementPermissions = managementPermissions[$scope.dataSource];
- // Pull user attribute schema
- schemaService.getUserAttributes($scope.dataSource).then(function attributesReceived(attributes) {
- $scope.attributes = attributes;
}, requestService.WARN);
- // Pull user data and permissions if we are editing an existing user
- if (username) {
-
- // Pull user data
- dataSourceService.apply(userService.getUser, dataSources, username)
- .then(function usersReceived(users) {
-
- // Get user for currently-selected data source
- $scope.users = users;
- $scope.user = users[$scope.dataSource];
-
- // Create skeleton user if user does not exist
- if (!$scope.user)
- $scope.user = new User({
- 'username' : username
- });
-
- }, requestService.WARN);
-
- // The current user will be associated with username of the existing
- // user in the retrieved permission set
- $scope.selfUsername = username;
-
- // Pull user permissions
- permissionService.getPermissions($scope.dataSource, username).then(function gotPermissions(permissions) {
- $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
- })
-
- // If permissions cannot be retrieved, use empty permissions
- ['catch'](requestService.createErrorCallback(function permissionRetrievalFailed() {
- $scope.permissionFlags = new PermissionFlagSet();
- }));
- }
-
- // If we are cloning an existing user, pull his/her data instead
- else if (cloneSourceUsername) {
-
- dataSourceService.apply(userService.getUser, dataSources, cloneSourceUsername)
- .then(function usersReceived(users) {
-
- // Get user for currently-selected data source
- $scope.users = {};
- $scope.user = users[$scope.dataSource];
-
- }, requestService.WARN);
-
- // The current user will be associated with cloneSourceUsername in the
- // retrieved permission set
- $scope.selfUsername = cloneSourceUsername;
-
- // Pull user permissions
- permissionService.getPermissions($scope.dataSource, cloneSourceUsername)
- .then(function gotPermissions(permissions) {
- $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
- $scope.permissionsAdded = permissions;
- })
-
- // If permissions cannot be retrieved, use empty permissions
- ['catch'](requestService.createErrorCallback(function permissionRetrievalFailed() {
- $scope.permissionFlags = new PermissionFlagSet();
- }));
- }
-
- // Use skeleton data if we are creating a new user
- else {
-
- // No users exist regardless of data source if there is no username
- $scope.users = {};
-
- // Use skeleton user object with no associated permissions
- $scope.user = new User();
- $scope.permissionFlags = new PermissionFlagSet();
-
- // As no permissions are yet associated with the user, it is safe to
- // use any non-empty username as a placeholder for self-referential
- // permissions
- $scope.selfUsername = 'SELF';
-
- }
-
- // Query the user's permissions for the current user
- dataSourceService.apply(
- permissionService.getEffectivePermissions,
- dataSources,
- currentUsername
- )
- .then(function permissionsReceived(permissions) {
- $scope.permissions = permissions;
- }, requestService.WARN);
-
- /**
- * The set of permissions that will be added to the user when the user is
- * saved. Permissions will only be present in this set if they are
- * manually added, and not later manually removed before saving.
- *
- * @type PermissionSet
- */
- $scope.permissionsAdded = new PermissionSet();
-
- /**
- * The set of permissions that will be removed from the user when the user
- * is saved. Permissions will only be present in this set if they are
- * manually removed, and not later manually added before saving.
- *
- * @type PermissionSet
- */
- $scope.permissionsRemoved = new PermissionSet();
-
/**
* Cancels all pending edits, returning to the management page.
*/
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/4f43ddc4/guacamole/src/main/webapp/app/manage/templates/manageUser.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
index 5fed148..24db74e 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html
@@ -11,12 +11,12 @@
</div>
<!-- Warn if user is read-only -->
- <div class="section" ng-show="isReadOnly()">
+ <div class="section" ng-hide="managementPermissions.canSaveObject">
<p class="notice read-only">{{'MANAGE_USER.INFO_READ_ONLY' | translate}}</p>
</div>
<!-- Sections applicable to non-read-only users -->
- <div ng-show="!isReadOnly()">
+ <div ng-show="managementPermissions.canSaveObject">
<!-- User password section -->
<div class="section">
@@ -40,13 +40,13 @@
</div>
<!-- User attributes section -->
- <div class="attributes" ng-show="canChangeAttributes()">
+ <div class="attributes" ng-show="managementPermissions.canChangeAttributes">
<guac-form namespace="'USER_ATTRIBUTES'" content="attributes"
- model="user.attributes" model-only="!canChangeAllAttributes()"></guac-form>
+ model="user.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
</div>
<!-- System permissions section -->
- <system-permission-editor ng-show="canChangePermissions()"
+ <system-permission-editor ng-show="managementPermissions.canChangePermissions"
username="selfUsername"
data-data-source="dataSource"
permission-flags="permissionFlags"
@@ -55,7 +55,7 @@
</system-permission-editor>
<!-- Connection permissions section -->
- <connection-permission-editor ng-show="canChangePermissions()"
+ <connection-permission-editor ng-show="managementPermissions.canChangePermissions"
data-data-source="dataSource"
permission-flags="permissionFlags"
permissions-added="permissionsAdded"
@@ -64,10 +64,10 @@
<!-- Form action buttons -->
<div class="action-buttons">
- <button ng-show="canSaveUser()" ng-click="saveUser()">{{'MANAGE_USER.ACTION_SAVE' | translate}}</button>
- <button ng-show="canCloneUser()" ng-click="cloneUser()">{{'MANAGE_USER.ACTION_CLONE' | translate}}</button>
+ <button ng-show="managementPermissions.canSaveObject" ng-click="saveUser()">{{'MANAGE_USER.ACTION_SAVE' | translate}}</button>
+ <button ng-show="managementPermissions.canCloneObject" ng-click="cloneUser()">{{'MANAGE_USER.ACTION_CLONE' | translate}}</button>
<button ng-click="cancel()">{{'MANAGE_USER.ACTION_CANCEL' | translate}}</button>
- <button ng-show="canDeleteUser()" ng-click="deleteUser()" class="danger">{{'MANAGE_USER.ACTION_DELETE' | translate}}</button>
+ <button ng-show="managementPermissions.canDeleteObject" ng-click="deleteUser()" class="danger">{{'MANAGE_USER.ACTION_DELETE' | translate}}</button>
</div>
</div>