From f564e26fd14690005ef486f4ded0e8fdafc04c43 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Dec 2014 01:40:23 -0800 Subject: [PATCH] GUAC-932: Provide flag-based view for PermissionSets. Use ngModel instead of ngChecked for permission checkboxes in user edit UI. --- .../controllers/manageUserController.js | 80 ++------- .../templates/connectionGroupPermission.html | 2 +- .../templates/connectionPermission.html | 2 +- .../app/manage/templates/manageUser.html | 2 +- .../app/rest/types/PermissionFlagSet.js | 155 ++++++++++++++++++ 5 files changed, 170 insertions(+), 71 deletions(-) create mode 100644 guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js index 25d38d3ef..faf35044c 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js @@ -27,8 +27,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto function manageUserController($scope, $injector) { // Required types - var ConnectionGroup = $injector.get('ConnectionGroup'); - var PermissionSet = $injector.get('PermissionSet'); + var ConnectionGroup = $injector.get('ConnectionGroup'); + var PermissionFlagSet = $injector.get('PermissionFlagSet'); + var PermissionSet = $injector.get('PermissionSet'); // Required services var $location = $injector.get('$location'); @@ -63,7 +64,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto // Pull user permissions permissionService.getPermissions(username).success(function gotPermissions(permissions) { - $scope.permissions = permissions; + $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions); }); // Retrieve all connections for which we have UPDATE permission @@ -101,76 +102,19 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto $scope.groupListContext = { /** - * Determines whether read permission for the connection having the - * given identifier is granted for the user being edited. - * - * @param {String} identifier - * The identifier of the connection to check. - * - * @returns {Boolean} - * true if the user has read permission for the given connection, - * false if the user lacks read permission, or the permissions have - * not yet been loaded. + * 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. */ - canReadConnection : function canReadConnection(identifier) { - - // Assume no permission if permissions not available yet - if (!$scope.permissions) - return false; - - // Return whether READ permission is present - return PermissionSet.hasConnectionPermission($scope.permissions, PermissionSet.ObjectPermissionType.READ, identifier); - - }, - - /** - * Determines whether read permission for the connection group having - * the given identifier is granted for the user being edited. - * - * @param {String} identifier - * The identifier of the connection group to check. - * - * @returns {Boolean} - * true if the user has read permission for the given connection - * group, false if the user lacks read permission, or the - * permissions have not yet been loaded. - */ - canReadConnectionGroup : function canReadConnectionGroup(identifier) { - - // Assume no permission if permissions not available yet - if (!$scope.permissions) - return false; - - // Return whether READ permission is present - return PermissionSet.hasConnectionGroupPermission($scope.permissions, PermissionSet.ObjectPermissionType.READ, identifier); - + getPermissionFlags : function getPermissionFlags() { + return $scope.permissionFlags; } }; - /** - * Determines whether the given system permission is granted for the - * user being edited. - * - * @param {String} type - * The type string of the system permission to check. - * - * @returns {Boolean} - * true if the user has the given system permission, false if the - * user lacks the given system permission, or the permissions have - * not yet been loaded. - */ - $scope.hasSystemPermission = function hasSystemPermission(type) { - - // Assume no permission if permissions not available yet - if (!$scope.permissions) - return false; - - // Return whether given permission is present - return PermissionSet.hasSystemPermission($scope.permissions, type); - - }; - /** * Cancels all pending edits, returning to the management page. */ diff --git a/guacamole/src/main/webapp/app/manage/templates/connectionGroupPermission.html b/guacamole/src/main/webapp/app/manage/templates/connectionGroupPermission.html index 0074b513d..1ca169386 100644 --- a/guacamole/src/main/webapp/app/manage/templates/connectionGroupPermission.html +++ b/guacamole/src/main/webapp/app/manage/templates/connectionGroupPermission.html @@ -21,6 +21,6 @@ THE SOFTWARE. --> - + {{item.name}} diff --git a/guacamole/src/main/webapp/app/manage/templates/connectionPermission.html b/guacamole/src/main/webapp/app/manage/templates/connectionPermission.html index c33f6018e..295bde763 100644 --- a/guacamole/src/main/webapp/app/manage/templates/connectionPermission.html +++ b/guacamole/src/main/webapp/app/manage/templates/connectionPermission.html @@ -27,7 +27,7 @@ - + {{item.name}} diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html index 0b02695ca..7a48014ab 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html @@ -53,7 +53,7 @@ THE SOFTWARE. - +
{{systemPermissionType.label | translate}}
diff --git a/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js b/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js new file mode 100644 index 000000000..197752379 --- /dev/null +++ b/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * A service for defining the PermissionFlagSet class. + */ +angular.module('rest').factory('PermissionFlagSet', ['PermissionSet', + function definePermissionFlagSet(PermissionSet) { + + /** + * Alternative view of a @link{PermissionSet} which allows manipulation of + * each permission through the setting (or retrieval) of boolean property + * values. + * + * @constructor + * @param {PermissionFlagSet|Object} template + * The object whose properties should be copied within the new + * PermissionFlagSet. + */ + var PermissionFlagSet = function PermissionFlagSet(template) { + + // Use empty object by default + template = template || {}; + + /** + * The granted state of each system permission, as a map of system + * permission type string to boolean value. A particular permission is + * granted if its corresponding boolean value is set to true. Valid + * permission type strings are defined within + * PermissionSet.SystemPermissionType. Permissions which are not + * granted may be set to false, but this is not required. + * + * @type Object. + */ + this.systemPermissions = template.systemPermissions || {}; + + /** + * The granted state of each permission for each connection, as a map + * of object permission type string to permission map. The permission + * map is, in turn, a map of connection identifier to boolean value. A + * particular permission is granted if its corresponding boolean value + * is set to true. Valid permission type strings are defined within + * PermissionSet.ObjectPermissionType. Permissions which are not + * granted may be set to false, but this is not required. + * + * @type Object.> + */ + this.connectionPermissions = template.connectionPermissions || {}; + + /** + * The granted state of each permission for each connection group, as a + * map of object permission type string to permission map. The + * permission map is, in turn, a map of connection group identifier to + * boolean value. A particular permission is granted if its + * corresponding boolean value is set to true. Valid permission type + * strings are defined within PermissionSet.ObjectPermissionType. + * Permissions which are not granted may be set to false, but this is + * not required. + * + * @type Object.> + */ + this.connectionGroupPermissions = template.connectionGroupPermissions || {}; + + /** + * The granted state of each permission for each user, as a map of + * object permission type string to permission map. The permission map + * is, in turn, a map of username to boolean value. A particular + * permission is granted if its corresponding boolean value is set to + * true. Valid permission type strings are defined within + * PermissionSet.ObjectPermissionType. Permissions which are not + * granted may be set to false, but this is not required. + * + * @type Object.> + */ + this.userPermissions = template.userPermissions || {}; + + }; + + var addObjectPermissions = function addObjectPermissions(permMap, flagMap) { + + // For each defined identifier in the permission map + for (var identifier in permMap) { + + // Pull the permission array and loop through each permission + var permissions = permMap[identifier]; + permissions.forEach(function addObjectPermission(type) { + + // Get identifier/flag mapping, creating first if necessary + var objectFlags = flagMap[type] = flagMap[type] || {}; + + // Set flag for current permission + objectFlags[identifier] = true; + + }); + + } + + }; + + /** + * Creates a new PermissionFlagSet, populating it with all the permissions + * indicated as granted within the given PermissionSet. + * + * @param {PermissionSet} permissionSet + * The PermissionSet containing the permissions to be copied into a new + * PermissionFlagSet. + * + * @returns {PermissionFlagSet} + * A new PermissionFlagSet containing flags representing all granted + * permissions from the given PermissionSet. + */ + PermissionFlagSet.fromPermissionSet = function fromPermissionSet(permissionSet) { + + var permissionFlagSet = new PermissionFlagSet(); + + // Add all granted system permissions + permissionSet.systemPermissions.forEach(function addSystemPermission(type) { + permissionFlagSet.systemPermissions[type] = true; + }); + + // Add all granted connection permissions + addObjectPermissions(permissionSet.connectionPermissions, permissionFlagSet.connectionPermissions); + + // Add all granted connection group permissions + addObjectPermissions(permissionSet.connectionGroupPermissions, permissionFlagSet.connectionGroupPermissions); + + // Add all granted user permissions + addObjectPermissions(permissionSet.userPermissions, permissionFlagSet.userPermissions); + + return permissionFlagSet; + + }; + + return PermissionFlagSet; + +}]); \ No newline at end of file