Github user necouchman commented on a diff in the pull request:
https://github.com/apache/guacamole-client/pull/282#discussion_r185627142
--- Diff:
guacamole/src/main/webapp/app/manage/controllers/manageUserController.js ---
@@ -361,727 +187,176 @@
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 || selectedDataSource;
-
- // The administrator can always save users
- if
(PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
-
- // 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);
-
- // Otherwise, can only save if we have permission to update this
user
- return
PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.UPDATE, username);
-
- };
-
- /**
- * Returns whether the current user can clone the user being edited
within
- * the given data source.
+ * @param {String} username
+ * The username of the user to load.
*
- * @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 clone the user being edited, false
- * otherwise.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been
prepared for
+ * editing the given user.
*/
- $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 || selectedDataSource;
-
- // If we are not editing an existing user, we cannot clone
- if (!$scope.userExists(selectedDataSource))
- return false;
-
- // The administrator can always clone users
- if
(PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
-
- // Otherwise we need explicit CREATE_USER permission
- return
PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.CREATE_USER);
-
- };
-
- /**
- * 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.
- *
- * @returns {Boolean}
- * true if the current user can delete the user being edited, false
- * otherwise.
- */
- $scope.canDeleteUser = function canDeleteUser(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;
-
- // Can't delete what doesn't exist
- if (!$scope.userExists(dataSource))
- return false;
-
- // The administrator can always delete users
- if
(PermissionSet.hasSystemPermission($scope.permissions[dataSource],
- PermissionSet.SystemPermissionType.ADMINISTER))
- return true;
-
- // Otherwise, require explicit DELETE permission on the user
- return
PermissionSet.hasUserPermission($scope.permissions[dataSource],
- PermissionSet.ObjectPermissionType.DELETE, username);
-
- };
-
- /**
- * 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.
- *
- * @returns {Boolean}
- * true if the user being edited is actually read-only and cannot
be
- * edited at all, false otherwise.
- */
- $scope.isReadOnly = function isReadOnly(dataSource) {
-
- // Use currently-selected data source if unspecified
- dataSource = dataSource || selectedDataSource;
-
- // User is read-only if they cannot be saved
- return !$scope.canSaveUser(dataSource);
-
- };
-
- // Update visible account pages whenever available users/permissions
changes
- $scope.$watchGroup(['users', 'permissions'], function
updateAccountPages() {
-
- // 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);
-
- // Account is not relevant if it does not exist and cannot be
- // created
- if (!linked && readOnly)
- return;
-
- // Only the selected data source is relevant when cloning
- if (cloneSourceUsername && dataSource !== selectedDataSource)
- return;
-
- // Determine class name based on read-only / linked status
- var className;
- if (readOnly) className = 'read-only';
- else if (linked) 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
- }));
-
- });
-
- });
-
- // Pull user attribute schema
- schemaService.getUserAttributes(selectedDataSource).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) {
+ 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) {
- // Get user for currently-selected data source
- $scope.users = users;
- $scope.user = users[selectedDataSource];
+ $scope.users = values.users;
+ $scope.user = values.users[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(selectedDataSource,
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[selectedDataSource];
-
- }, requestService.WARN);
-
- // The current user will be associated with cloneSourceUsername in
the
- // retrieved permission set
- $scope.selfUsername = cloneSourceUsername;
+ // 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);
- // Pull user permissions
- permissionService.getPermissions(selectedDataSource,
cloneSourceUsername)
- .then(function gotPermissions(permissions) {
- $scope.permissionFlags =
PermissionFlagSet.fromPermissionSet(permissions);
- 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();
-
- }
-
- /**
- * 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,
- dataSources,
- currentUsername
- )
- .then(function permissionsReceived(permissions) {
- $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
- * manually added, and not later manually removed before saving.
- *
- * @type PermissionSet
- */
- var 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
- */
- 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.
+ * Loads the data associated with the user having the given username,
+ * preparing the interface for cloning that existing user.
*
- * @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} dataSource
+ * The unique identifier of the data source containing the user to
+ * be cloned.
*
- * @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} username
+ * The username of the user being cloned.
*
- * @param {String} identifier
- * The identifier of the user affected by the permission being
added.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been
prepared for
+ * cloning the given user.
*/
- 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) {
+ 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) {
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasUserPermission(permissionsAdded, type,
identifier))
- PermissionSet.removeUserPermission(permissionsAdded, type,
identifier);
+ $scope.users = {};
+ $scope.user = values.users[dataSource];
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addUserPermission(permissionsRemoved, type,
identifier);
+ // 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;
+ });
};
/**
- * Notifies the controller that a change has been made to the given
user
- * permission for the user being edited.
+ * Loads skeleton user data, preparing the interface for creating a new
+ * user.
*
- * @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.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been
prepared for
+ * creating a new user.
*/
- $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);
+ var loadSkeletonUser = function loadSkeletonUser() {
- };
+ // No users exist regardless of data source if there is no username
+ $scope.users = {};
- /**
- * 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) {
+ // Use skeleton user object with no associated permissions
+ $scope.user = new User();
+ $scope.permissionFlags = new PermissionFlagSet();
- // If permission was previously removed, simply un-remove it
- if (PermissionSet.hasConnectionPermission(permissionsRemoved,
PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionPermission(permissionsRemoved,
PermissionSet.ObjectPermissionType.READ, identifier);
+ // 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, explicitly add the permission
- else
- PermissionSet.addConnectionPermission(permissionsAdded,
PermissionSet.ObjectPermissionType.READ, identifier);
+ return $q.resolve();
};
/**
- * Updates the permissionsAdded and permissionsRemoved permission sets
to
- * reflect the removal of the given connection permission.
+ * 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.
*
- * @param {String} identifier
- * The identifier of the connection to remove READ permission for.
+ * @returns {Promise}
+ * A promise which is resolved when the interface has been prepared
+ * for performing the requested management task.
*/
- var removeConnectionPermission = function
removeConnectionPermission(identifier) {
+ var loadRequestedUser = function loadRequestedUser() {
- // If permission was previously added, simply un-add it
- if (PermissionSet.hasConnectionPermission(permissionsAdded,
PermissionSet.ObjectPermissionType.READ, identifier))
- PermissionSet.removeConnectionPermission(permissionsAdded,
PermissionSet.ObjectPermissionType.READ, identifier);
+ // Pull user data and permissions if we are editing an existing
user
+ if (username)
+ return loadExistingUser($scope.dataSource, username);
- // Otherwise, explicitly remove the permission
- else
- PermissionSet.addConnectionPermission(permissionsRemoved,
PermissionSet.ObjectPermissionType.READ, identifier);
+ // If we are cloning an existing user, pull his/her data instead
+ if (cloneSourceUsername)
+ return loadClonedUser($scope.dataSource, cloneSourceUsername);
- };
-
- /**
- * 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);
+ return loadSkeletonUser();
--- End diff --
Nitpick: in the other places where you updated this, you commented on this
action. For consistency's sake, I'd say either remove the comments above the
other's or add one, here.
---