From b1db52541d41d35425b8f306dd3ea5eb086a017a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 12 Dec 2014 15:18:21 -0800 Subject: [PATCH] GUAC-932: Remove filtering user service. Add permission filtering support to user retrieval endpoint. --- .../guacamole/net/basic/rest/RESTModule.java | 2 - .../permission/PermissionRESTService.java | 1 - .../net/basic/rest/user/UserRESTService.java | 46 +++++++++++---- .../net/basic/rest/user/UserService.java | 59 ------------------- .../manage/controllers/manageController.js | 28 ++++----- .../app/rest/services/legacyUserService.js | 57 ------------------ .../webapp/app/rest/services/userService.js | 29 +++++++-- 7 files changed, 69 insertions(+), 153 deletions(-) delete mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserService.java delete mode 100644 guacamole/src/main/webapp/app/rest/services/legacyUserService.js diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java index 55e473755..c9ed5a30a 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java @@ -27,7 +27,6 @@ import org.glyptodon.guacamole.net.basic.rest.connection.ConnectionService; import org.glyptodon.guacamole.net.basic.rest.connectiongroup.ConnectionGroupService; import org.glyptodon.guacamole.net.basic.rest.permission.PermissionService; import org.glyptodon.guacamole.net.basic.rest.protocol.ProtocolRetrievalService; -import org.glyptodon.guacamole.net.basic.rest.user.UserService; /** * A Guice Module for setting up dependency injection for the @@ -44,7 +43,6 @@ public class RESTModule extends AbstractModule { bind(ConnectionService.class); bind(ConnectionGroupService.class); bind(PermissionService.class); - bind(UserService.class); bind(ProtocolRetrievalService.class); } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/permission/PermissionRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/permission/PermissionRESTService.java index 573763437..85760f5a4 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/permission/PermissionRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/permission/PermissionRESTService.java @@ -28,7 +28,6 @@ import java.util.List; import java.util.Map; import javax.ws.rs.Consumes; import javax.ws.rs.GET; -import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java index 176615b1d..fdc66fd7d 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java @@ -23,6 +23,7 @@ package org.glyptodon.guacamole.net.basic.rest.user; import com.google.inject.Inject; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.ws.rs.Consumes; @@ -39,6 +40,7 @@ import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.auth.Directory; import org.glyptodon.guacamole.net.auth.User; import org.glyptodon.guacamole.net.auth.UserContext; +import org.glyptodon.guacamole.net.auth.permission.UserPermission; import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.HTTPException; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; @@ -67,29 +69,47 @@ public class UserRESTService { private AuthenticationService authenticationService; /** - * A service for managing the REST endpoint APIPermission objects. - */ - @Inject - private UserService userService; - - /** - * Gets a list of users in the system. - * @param authToken The authentication token that is used to authenticate - * the user performing the operation. + * Gets a list of users in the system, filtering the returned list by the + * given permission, if specified. + * + * @param authToken + * The authentication token that is used to authenticate the user + * performing the operation. + * + * @param permission + * If specified, limit the returned list to only those users for whom + * the current user has the given permission. Otherwise, all visible + * users are returned. + * * @return The user list. - * @throws GuacamoleException If a problem is encountered while listing users. + * + * @throws GuacamoleException + * If an error is encountered while retrieving users. */ @GET @AuthProviderRESTExposure - public List getUsers(@QueryParam("token") String authToken) throws GuacamoleException { + public List getUsers(@QueryParam("token") String authToken, + @QueryParam("permission") UserPermission.Type permission) + throws GuacamoleException { UserContext userContext = authenticationService.getUserContext(authToken); + User self = userContext.self(); // Get the directory Directory userDirectory = userContext.getUserDirectory(); - // Convert and return the user directory listing - return userService.convertUserList(userDirectory); + List users = new ArrayList(); + + // Add all users matching the given permission filter + for (String username : userDirectory.getIdentifiers()) { + + if (permission == null || self.hasPermission(new UserPermission(permission, username))) + users.add(new APIUser(userDirectory.get(username))); + + } + + // Return the user directory listing + return users; } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserService.java deleted file mode 100644 index c671b5246..000000000 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserService.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -package org.glyptodon.guacamole.net.basic.rest.user; - -import java.util.ArrayList; -import java.util.List; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.net.auth.Directory; -import org.glyptodon.guacamole.net.auth.User; - -/** - * A service for performing useful manipulations on REST Users. - * - * @author James Muehlner - */ -public class UserService { - - /** - * Converts a user directory to a list of APIUser objects for - * exposing with the REST endpoints. - * - * @param userDirectory The user directory to convert for REST endpoint use. - * @return A List of APIUser objects for use with the REST endpoint. - * @throws GuacamoleException If an error occurs while converting the - * user directory. - */ - public List convertUserList(Directory userDirectory) - throws GuacamoleException { - - List restUsers = new ArrayList(); - - for(String username : userDirectory.getIdentifiers()) - restUsers.add(new APIUser(userDirectory.get(username))); - - return restUsers; - - } - -} diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageController.js b/guacamole/src/main/webapp/app/manage/controllers/manageController.js index 32b37c4c8..b3a771975 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageController.js @@ -25,15 +25,17 @@ */ angular.module('manage').controller('manageController', ['$scope', '$injector', function manageController($scope, $injector) { - - // Get the dependencies commonJS style + + // Required types + var Permission = $injector.get('Permission'); + + // Required services var legacyConnectionGroupService = $injector.get('legacyConnectionGroupService'); var connectionEditModal = $injector.get('connectionEditModal'); var connectionGroupEditModal = $injector.get('connectionGroupEditModal'); var userEditModal = $injector.get('userEditModal'); - var protocolService = $injector.get('protocolService'); - var userService = $injector.get('userService'); - var legacyUserService = $injector.get('legacyUserService'); + var protocolService = $injector.get('protocolService'); + var userService = $injector.get('userService'); // Set status to loading until we have all the connections, groups, and users have loaded $scope.loadingUsers = true; @@ -64,21 +66,13 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', $scope.loadingConnections = false; }); - - userService.getUsers().success(function filterEditableUsers(users) { + + // Retrieve all users for whom we have UPDATE permission + userService.getUsers(Permission.Type.UPDATE).success(function usersReceived(users) { $scope.users = users; - - // Filter the users to only include ones that we have UPDATE for - if(!$scope.currentUserIsAdmin) { - legacyUserService.filterUsersByPermission( - $scope.users, - $scope.currentUserPermissions, - 'UPDATE' - ); - } - $scope.loadingUsers = false; }); + }); /** diff --git a/guacamole/src/main/webapp/app/rest/services/legacyUserService.js b/guacamole/src/main/webapp/app/rest/services/legacyUserService.js deleted file mode 100644 index 894958a2c..000000000 --- a/guacamole/src/main/webapp/app/rest/services/legacyUserService.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 performing useful user related functionaltiy. - */ -angular.module('rest').factory('legacyUserService', ['$injector', function legacyUserService($injector) { - - var permissionCheckService = $injector.get('permissionCheckService'); - - var service = {}; - - /** - * Filters the list of users using the provided permissions. - * - * @param {array} users The user list. - * - * @param {object} permissionList The list of permissions to use - * when filtering. - * - * @param {object} permissionCriteria The required permission for each user. - * - * @return {array} The filtered list. - */ - service.filterUsersByPermission = function filterUsersByPermission(users, permissionList, permissionCriteria) { - for(var i = 0; i < users.length; i++) { - if(!permissionCheckService.checkPermission(permissionList, - "USER", user.username, permissionCriteria)) { - items.splice(i, 1); - continue; - } - } - - return users; - }; - - return service; -}]); diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js index d5c1431d9..2a42d5a8d 100644 --- a/guacamole/src/main/webapp/app/rest/services/userService.js +++ b/guacamole/src/main/webapp/app/rest/services/userService.js @@ -33,21 +33,42 @@ angular.module('rest').factory('userService', ['$http', 'authenticationService', * returning a promise that provides an array of @link{User} objects if * successful. * + * @param {String} [permissionType] + * The permission type string of the permission that the current user + * must have for a given user to appear within the list. Valid values + * are listed within Permission.Type. + * * @returns {Promise.} * A promise which will resolve with an array of @link{User} objects * upon success. */ - service.getUsers = function getUsers() { - return $http.get("api/user?token=" + authenticationService.getCurrentToken()); + service.getUsers = function getUsers(permissionType) { + + // Build HTTP parameters set + var httpParameters = { + token : authenticationService.getCurrentToken() + }; + + // Add permission filter if specified + if (permissionType) + httpParameters.permission = permissionType; + + // Retrieve users + return $http({ + method : 'GET', + url : 'api/user', + params : httpParameters + }); + }; - + /** * Makes a request to the REST API to get the user having the given ID, * returning a promise that provides the corresponding @link{User} if * successful. * * @param {String} userID The ID of the user to retrieve. - * + * * @returns {Promise.} * A promise which will resolve with a @link{User} upon success. */