GUACAMOLE-220: Allow manipulation and retrieval of user group permissions via JavaScript.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/55bcf25a Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/55bcf25a Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/55bcf25a Branch: refs/heads/staging/1.0.0 Commit: 55bcf25a1c53f85ba2383fc83b46e2bc2ccd05af Parents: 9f01fcb Author: Michael Jumper <mjum...@apache.org> Authored: Thu Apr 19 14:39:04 2018 -0700 Committer: Michael Jumper <mjum...@apache.org> Committed: Wed Aug 8 09:00:06 2018 -0700 ---------------------------------------------------------------------- .../app/rest/services/permissionService.js | 91 +++++++++++++------- .../webapp/app/rest/types/PermissionFlagSet.js | 23 ++++- .../main/webapp/app/rest/types/PermissionSet.js | 82 +++++++++++++++++- 3 files changed, 163 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/55bcf25a/guacamole/src/main/webapp/app/rest/services/permissionService.js ---------------------------------------------------------------------- diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js index 6d3dfdf..21c5a02 100644 --- a/guacamole/src/main/webapp/app/rest/services/permissionService.js +++ b/guacamole/src/main/webapp/app/rest/services/permissionService.js @@ -45,6 +45,11 @@ angular.module('rest').factory('permissionService', ['$injector', * within that data source (and thus cannot be found beneath * "api/session/data/{dataSource}/users") * + * NOTE: Unlike getPermissionsResourceURL(), + * getEffectivePermissionsResourceURL() CANNOT be applied to user groups. + * Only users have retrievable effective permissions as far as the REST API + * is concerned. + * * @param {String} dataSource * The unique identifier of the data source containing the user whose * permissions should be retrieved. This identifier corresponds to an @@ -82,6 +87,10 @@ angular.module('rest').factory('permissionService', ['$injector', * from the permissions returned via getPermissions() in that permissions * which are not directly granted to the user are included. * + * NOTE: Unlike getPermissions(), getEffectivePermissions() CANNOT be + * applied to user groups. Only users have retrievable effective + * permissions as far as the REST API is concerned. + * * @param {String} dataSource * The unique identifier of the data source containing the user whose * permissions should be retrieved. This identifier corresponds to an @@ -113,10 +122,10 @@ angular.module('rest').factory('permissionService', ['$injector', /** * Returns the URL for the REST resource most appropriate for accessing - * the permissions of the user having the given identifier. The permissions - * retrieved differ from effective permissions (those returned by - * getEffectivePermissions()) in that only permissions which are directly - * granted to the user are included. + * the permissions of the user or group having the given identifier. The + * permissions retrieved differ from effective permissions (those returned + * by getEffectivePermissions()) in that only permissions which are directly + * granted to the user or group are included. * * It is important to note that a particular data source can authenticate * and provide permissions for a user, even if that user does not exist @@ -129,18 +138,27 @@ angular.module('rest').factory('permissionService', ['$injector', * AuthenticationProvider within the Guacamole web application. * * @param {String} identifier - * The identifier of the user for which the URL of the proper REST - * resource should be derived. + * The identifier of the user or group for which the URL of the proper + * REST resource should be derived. + * + * @param {Boolean} [group] + * Whether the provided identifier refers to a user group. If false or + * omitted, the identifier given is assumed to refer to a user. * * @returns {String} - * The URL for the REST resource representing the user having the given - * identifier. + * The URL for the REST resource representing the user or group having + * the given identifier. */ - var getPermissionsResourceURL = function getPermissionsResourceURL(dataSource, identifier) { + var getPermissionsResourceURL = function getPermissionsResourceURL(dataSource, identifier, group) { // Create base URL for data source var base = 'api/session/data/' + encodeURIComponent(dataSource); + // Access group permissions directly (there is no "self" for user groups + // as there is for users) + if (group) + return base + '/userGroups/' + encodeURIComponent(identifier) + '/permissions'; + // If the username is that of the current user, do not rely on the // user actually existing (they may not). Access their permissions via // "self" rather than the collection of defined users. @@ -155,36 +173,41 @@ angular.module('rest').factory('permissionService', ['$injector', /** * Makes a request to the REST API to get the list of permissions for a - * given user, returning a promise that provides an array of + * given user or user group, returning a promise that provides an array of * @link{Permission} objects if successful. The permissions retrieved * differ from effective permissions (those returned by - * getEffectivePermissions()) in that only permissions which are directly - * granted to the user included. + * getEffectivePermissions()) in that both users and groups may be queried, + * and only permissions which are directly granted to the user or group are + * included. * * @param {String} dataSource - * The unique identifier of the data source containing the user whose - * permissions should be retrieved. This identifier corresponds to an - * AuthenticationProvider within the Guacamole web application. + * The unique identifier of the data source containing the user or group + * whose permissions should be retrieved. This identifier corresponds to + * an AuthenticationProvider within the Guacamole web application. * * @param {String} identifier - * The identifier of the user to retrieve the permissions for. + * The identifier of the user or group to retrieve the permissions for. + * + * @param {Boolean} [group] + * Whether the provided identifier refers to a user group. If false or + * omitted, the identifier given is assumed to refer to a user. * * @returns {Promise.<PermissionSet>} * A promise which will resolve with a @link{PermissionSet} upon * success. */ - service.getPermissions = function getPermissions(dataSource, identifier) { + service.getPermissions = function getPermissions(dataSource, identifier, group) { // Build HTTP parameters set var httpParameters = { token : authenticationService.getCurrentToken() }; - // Retrieve user permissions + // Retrieve user/group permissions return requestService({ cache : cacheService.users, method : 'GET', - url : getPermissionsResourceURL(dataSource, identifier), + url : getPermissionsResourceURL(dataSource, identifier, group), params : httpParameters }); @@ -261,6 +284,10 @@ angular.module('rest').factory('permissionService', ['$injector', addObjectPatchOperations(patch, operation, "/userPermissions", permissions.userPermissions); + // Add user group permission operations to patch + addObjectPatchOperations(patch, operation, "/userGroupPermissions", + permissions.userGroupPermissions); + // Add system operations to patch permissions.systemPermissions.forEach(function addSystemPatch(type) { patch.push({ @@ -274,18 +301,18 @@ angular.module('rest').factory('permissionService', ['$injector', /** * Makes a request to the REST API to modify the permissions for a given - * user, returning a promise that can be used for processing the results of - * the call. This request affects only the permissions directly granted to - * the user, and may not affect permissions inherited through other means - * (effective permissions). + * user or group, returning a promise that can be used for processing the + * results of the call. This request affects only the permissions directly + * granted to the user or group, and may not affect permissions inherited + * through other means (effective permissions). * * @param {String} dataSource - * The unique identifier of the data source containing the user whose - * permissions should be modified. This identifier corresponds to an - * AuthenticationProvider within the Guacamole web application. + * The unique identifier of the data source containing the user or group + * whose permissions should be modified. This identifier corresponds to + * an AuthenticationProvider within the Guacamole web application. * * @param {String} identifier - * The identifier of the user to modify the permissions of. + * The identifier of the user or group to modify the permissions of. * * @param {PermissionSet} [permissionsToAdd] * The set of permissions to add, if any. @@ -293,12 +320,16 @@ angular.module('rest').factory('permissionService', ['$injector', * @param {PermissionSet} [permissionsToRemove] * The set of permissions to remove, if any. * + * @param {Boolean} [group] + * Whether the provided identifier refers to a user group. If false or + * omitted, the identifier given is assumed to refer to a user. + * * @returns {Promise} * A promise for the HTTP call which will succeed if and only if the * patch operation is successful. */ service.patchPermissions = function patchPermissions(dataSource, identifier, - permissionsToAdd, permissionsToRemove) { + permissionsToAdd, permissionsToRemove, group) { var permissionPatch = []; @@ -313,10 +344,10 @@ angular.module('rest').factory('permissionService', ['$injector', // Add all the remove operations to the patch addPatchOperations(permissionPatch, PermissionPatch.Operation.REMOVE, permissionsToRemove); - // Patch user permissions + // Patch user/group permissions return requestService({ method : 'PATCH', - url : getPermissionsResourceURL(dataSource, identifier), + url : getPermissionsResourceURL(dataSource, identifier, group), params : httpParameters, data : permissionPatch }) http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/55bcf25a/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js ---------------------------------------------------------------------- diff --git a/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js b/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js index 64b942b..f79e3b9 100644 --- a/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js +++ b/guacamole/src/main/webapp/app/rest/types/PermissionFlagSet.js @@ -133,7 +133,7 @@ angular.module('rest').factory('PermissionFlagSet', ['PermissionSet', * 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.<String, Object.<String, Boolean>> */ this.userPermissions = template.userPermissions || { @@ -143,6 +143,24 @@ angular.module('rest').factory('PermissionFlagSet', ['PermissionSet', 'ADMINISTER' : {} }; + /** + * The granted state of each permission for each user group, as a map of + * object permission type string to permission map. The permission map + * is, in turn, a map of 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.<String, Object.<String, Boolean>> + */ + this.userGroupPermissions = template.userGroupPermissions || { + 'READ' : {}, + 'UPDATE' : {}, + 'DELETE' : {}, + 'ADMINISTER' : {} + }; + }; /** @@ -216,6 +234,9 @@ angular.module('rest').factory('PermissionFlagSet', ['PermissionSet', // Add all granted user permissions addObjectPermissions(permissionSet.userPermissions, permissionFlagSet.userPermissions); + // Add all granted user group permissions + addObjectPermissions(permissionSet.userGroupPermissions, permissionFlagSet.userGroupPermissions); + return permissionFlagSet; }; http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/55bcf25a/guacamole/src/main/webapp/app/rest/types/PermissionSet.js ---------------------------------------------------------------------- diff --git a/guacamole/src/main/webapp/app/rest/types/PermissionSet.js b/guacamole/src/main/webapp/app/rest/types/PermissionSet.js index 8fd1ef6..2bc2e9e 100644 --- a/guacamole/src/main/webapp/app/rest/types/PermissionSet.js +++ b/guacamole/src/main/webapp/app/rest/types/PermissionSet.js @@ -82,6 +82,15 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() this.userPermissions = template.userPermissions || {}; /** + * Map of user group identifiers to the corresponding array of granted + * permissions. Each permission is represented by a string listed + * within PermissionSet.ObjectPermissionType. + * + * @type Object.<String, String[]> + */ + this.userGroupPermissions = template.userGroupPermissions || {}; + + /** * Array of granted system permissions. Each permission is represented * by a string listed within PermissionSet.SystemPermissionType. * @@ -306,7 +315,7 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() }; /** - * Returns whether the given permission is granted for the user having the + * Returns whether the given permission is granted for the user having the * given ID. * * @param {PermissionSet|Object} permSet @@ -315,7 +324,7 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() * @param {String} type * The permission to search for, as defined by * PermissionSet.ObjectPermissionType. - * + * * @param {String} identifier * The identifier of the user to which the permission applies. * @@ -327,6 +336,27 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() }; /** + * Returns whether the given permission is granted for the user group having + * the given identifier. + * + * @param {PermissionSet|Object} permSet + * The permission set to check. + * + * @param {String} type + * The permission to search for, as defined by + * PermissionSet.ObjectPermissionType. + * + * @param {String} identifier + * The identifier of the user group to which the permission applies. + * + * @returns {Boolean} + * true if the permission is present (granted), false otherwise. + */ + PermissionSet.hasUserGroupPermission = function hasUserGroupPermission(permSet, type, identifier) { + return hasPermission(permSet.userGroupPermissions, type, identifier); + }; + + /** * Returns whether the given permission is granted at the system level. * * @param {PermissionSet|Object} permSet @@ -733,6 +763,54 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() return removeObjectPermission(permSet.userPermissions, type, identifier); }; + /** + * Adds the given user group permission applying to the user group with the + * given identifier to the given permission set, if not already present. If + * the permission is already present, this function has no effect. + * + * @param {PermissionSet} permSet + * The permission set to modify. + * + * @param {String} type + * The permission to add, as defined by + * PermissionSet.ObjectPermissionType. + * + * @param {String} identifier + * The identifier of the user group to which the permission applies. + * + * @returns {Boolean} + * true if the permission was added, false if the permission was + * already present in the given permission set. + */ + PermissionSet.addUserGroupPermission = function addUserGroupPermission(permSet, type, identifier) { + permSet.userGroupPermissions = permSet.userGroupPermissions || {}; + return addObjectPermission(permSet.userGroupPermissions, type, identifier); + }; + + /** + * Removes the given user group permission applying to the user group with + * the given identifier from the given permission set, if present. If the + * permission is not present, this function has no effect. + * + * @param {PermissionSet} permSet + * The permission set to modify. + * + * @param {String} type + * The permission to remove, as defined by + * PermissionSet.ObjectPermissionType. + * + * @param {String} identifier + * The identifier of the user group to whom the permission applies. + * + * @returns {Boolean} + * true if the permission was removed, false if the permission was not + * present in the given permission set. + */ + PermissionSet.removeUserGroupPermission = function removeUserGroupPermission(permSet, type, identifier) { + permSet.userGroupPermissions = permSet.userGroupPermissions || {}; + return removeObjectPermission(permSet.userGroupPermissions, type, identifier); + }; + return PermissionSet; }]); \ No newline at end of file